<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>面试- 小册 | 爪哇干货分享</title>
    <meta name="generator" content="VuePress 1.9.7">
    <link rel="icon" href="/favicon.ico">
    <script charset="utf-8" async="async" src="/js/jquery.min.js"></script>
    <script charset="utf-8" async="async" src="/js/global.js"></script>
    <script charset="utf-8" async="async" src="/js/fingerprint2.min.js"></script>
    <script charset="utf-8" async="async" src="https://s9.cnzz.com/z_stat.php?id=1278232949&amp;web_id=1278232949"></script>
    <script>
              var _hmt = _hmt || [];
              (function() {
                var hm = document.createElement("script");
                hm.src = "https://hm.baidu.com/hm.js?e68b39347be2339192f80082c317901e";
                var s = document.getElementsByTagName("script")[0];
                s.parentNode.insertBefore(hm, s);
              })();
            </script>
    <meta name="description" content="包含: Java 基础，面试小册，Spring源码解析，中间件原理">
    <meta property="article:modified_time" content="2022-03-30T11:44:00.000Z">
    <meta property="og:title" content="面试- 小册">
    <meta property="og:type" content="article">
    <meta property="og:url" content="/md/java/interview/book.html">
    <meta name="twitter:title" content="面试- 小册">
    <meta name="twitter:url" content="/md/java/interview/book.html">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="robots" content="all">
    <meta name="author" content="janker">
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Expires" content="0">
    <meta name="keywords" content="爪哇干货分享,  中间件, Spring, Java基础, 面试小册">
    <meta name="apple-mobile-web-app-capable" content="yes">
    
    <link rel="preload" href="/assets/css/0.styles.b854e512.css" as="style"><link rel="preload" href="/assets/css/styles.css?v=1648640762568" as="style"><link rel="preload" href="/assets/js/cg-styles.js?v=1648640762568" as="script"><link rel="preload" href="/assets/js/cg-app.js?v=1648640762568" as="script"><link rel="preload" href="/assets/js/cg-4.js?v=1648640762568" as="script"><link rel="preload" href="/assets/js/cg-3.js?v=1648640762568" as="script"><link rel="preload" href="/assets/js/cg-23.js?v=1648640762568" as="script"><link rel="preload" href="/assets/js/cg-5.js?v=1648640762568" as="script"><link rel="preload" href="/assets/js/cg-6.js?v=1648640762568" as="script">
    <link rel="stylesheet" href="/assets/css/0.styles.b854e512.css"><link rel="stylesheet" href="/assets/css/styles.css?v=1648640762568">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">爪哇干货分享</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/md/other/guide-to-reading.html" class="nav-link">
  导读
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Java" class="dropdown-title"><span class="title">Java</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/md/java/interview/book.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  面经手册
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="方法" class="dropdown-title"><span class="title">方法</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/md/dev-spec/pattern/1_overview.html" class="nav-link">
  设计模式
</a></li></ul></div></div><div class="nav-item"><a href="/md/about/me/about-me.html" class="nav-link">
  关于
</a></div><div class="nav-item"><a href="https://github.com/janker0718/ShareJava" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/md/other/guide-to-reading.html" class="nav-link">
  导读
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Java" class="dropdown-title"><span class="title">Java</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/md/java/interview/book.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  面经手册
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="方法" class="dropdown-title"><span class="title">方法</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/md/dev-spec/pattern/1_overview.html" class="nav-link">
  设计模式
</a></li></ul></div></div><div class="nav-item"><a href="/md/about/me/about-me.html" class="nav-link">
  关于
</a></div><div class="nav-item"><a href="https://github.com/janker0718/ShareJava" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>面试</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/md/java/interview/book.html" aria-current="page" class="active sidebar-link">面试- 小册</a></li><li><a href="/md/java/interview/resume.html" class="sidebar-link">面试 - 简历</a></li></ul></section></li></ul> </aside> <div><main class="page"> <div class="theme-default-content content__default"><h1 id="面试-小册"><a href="#面试-小册" class="header-anchor">#</a> 面试 - 小册</h1> <div class="custom-block tip"><p class="custom-block-title">To 我</p> <p>知其然，知其所以然，忙时做业绩，闲时修内功。  by janker</p></div> <p></p><div class="table-of-contents"><ul><li><a href="#jvm">JVM</a><ul><li><a href="#jvm内存模型-gc机制和原理">JVM内存模型，GC机制和原理;</a></li><li><a href="#gc分哪两种-minor-gc-和full-gc有什么区别-什么时候会触发full-gc-分别采用什么算法">GC分哪两种，Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?</a></li><li><a href="#jvm里的有几种classloader-为什么会有多种">JVM里的有几种classloader，为什么会有多种?</a></li><li><a href="#什么是双亲委派机制-介绍一些运作过程-双亲委派模型的好处">什么是双亲委派机制?介绍一些运作过程，双亲委派模型的好处;</a></li><li><a href="#什么情况下我们需要破坏双亲委派模型">什么情况下我们需要破坏双亲委派模型;</a></li><li><a href="#常见的jvm调优方法有哪些-可以具体到调整哪个参数-调成什么值">常见的JVM调优方法有哪些?可以具体到调整哪个参数，调成什么值?</a></li><li><a href="#jvm虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的">JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;</a></li></ul></li><li><a href="#java基础、java进阶">Java基础、Java进阶</a><ul><li><a href="#红黑树的实现原理和应用场景">红黑树的实现原理和应用场景;</a></li><li><a href="#nio是什么-适用于何种场景">NIO是什么?适用于何种场景?</a></li><li><a href="#java9比java8改进了什么">Java9比Java8改进了什么;</a></li><li><a href="#hashmap内部的数据结构是什么-底层是怎么实现的">HashMap内部的数据结构是什么?底层是怎么实现的?</a></li><li><a href="#说说反射的用途及实现-反射是不是很慢-我们在项目中是否要避免使用反射">说说反射的用途及实现，反射是不是很慢，我们在项目中是否要避免使用反射;</a></li><li><a href="#说说自定义注解的场景及实现">说说自定义注解的场景及实现;</a></li><li><a href="#list-和-map-区别">List 和 Map 区别</a></li><li><a href="#arraylist-与-linkedlist-区别-arraylist-与-vector-区别">Arraylist 与 LinkedList 区别，ArrayList 与 Vector 区别;</a></li></ul></li><li><a href="#多线程并发">多线程并发</a><ul><li><a href="#线程池的原理-为什么要创建线程池-创建线程池的方式">线程池的原理，为什么要创建线程池?创建线程池的方式;</a></li><li><a href="#线程的生命周期-什么时候会出现僵死进程">线程的生命周期，什么时候会出现僵死进程;</a></li><li><a href="#说说线程安全问题-什么实现线程安全-如何实现线程安全">说说线程安全问题，什么实现线程安全，如何实现线程安全;</a></li><li><a href="#创建线程池有哪几个核心参数-如何合理配置线程池的大小">创建线程池有哪几个核心参数? 如何合理配置线程池的大小?</a></li><li><a href="#volatile、threadlocal的使用场景和原理">volatile、ThreadLocal的使用场景和原理;</a></li><li><a href="#threadlocal-什么时候会出现oom的情况-为什么">ThreadLocal 什么时候会出现OOM的情况?为什么?</a></li><li><a href="#synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性">synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;</a></li></ul></li><li><a href="#spring">Spring</a><ul><li><a href="#spring-aop的实现原理和场景">Spring AOP的实现原理和场景?</a></li><li><a href="#spring-bean的作用域和生命周期">Spring bean的作用域和生命周期;</a></li><li><a href="#spring-boot比spring做了哪些改进">Spring Boot比Spring做了哪些改进?</a></li><li><a href="#spring-5比spring4做了哪些改进">Spring 5比Spring4做了哪些改进;</a></li><li><a href="#如何自定义一个spring-boot-starter">如何自定义一个Spring Boot Starter?</a></li><li><a href="#spring-ioc是什么-优点是什么">Spring IOC是什么?优点是什么?</a></li><li><a href="#springmvc、动态代理、反射、aop原理、事务隔离级别">SpringMVC、动态代理、反射、AOP原理、事务隔离级别;</a></li></ul></li><li><a href="#框架-中间件">框架|中间件</a><ul><li><a href="#redis">Redis</a></li><li><a href="#dubbo">Dubbo</a></li><li><a href="#spring-cloud">Spring Cloud</a></li><li><a href="#消息队列">消息队列</a></li></ul></li><li><a href="#数据库">数据库</a><ul><li><a href="#锁机制介绍-行锁、表锁、排他锁、共享锁">锁机制介绍:行锁、表锁、排他锁、共享锁;</a></li><li><a href="#乐观锁的业务场景及实现方式">乐观锁的业务场景及实现方式;</a></li><li><a href="#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交">事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</a></li><li><a href="#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么">MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</a></li><li><a href="#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁">MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</a></li><li><a href="#分布式事务的原理2阶段提交-同步异步阻塞非阻塞">分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</a></li><li><a href="#数据库事务隔离级别-mysql默认的隔离级别">数据库事务隔离级别，MySQL默认的隔离级别;</a></li><li><a href="#spring如何实现事务">Spring如何实现事务;</a></li><li><a href="#jdbc如何实现事务">JDBC如何实现事务;</a></li><li><a href="#嵌套事务实现">嵌套事务实现；</a></li><li><a href="#分布式事务实现">分布式事务实现;</a></li><li><a href="#sql的整个解析、执行过程原理、sql行转列">SQL的整个解析、执行过程原理、SQL行转列;</a></li><li><a href="#dubbo">Dubbo</a></li><li><a href="#spring-cloud">Spring Cloud</a></li><li><a href="#消息队列">消息队列</a></li></ul></li><li><a href="#数据库">数据库</a><ul><li><a href="#锁机制介绍-行锁、表锁、排他锁、共享锁">锁机制介绍:行锁、表锁、排他锁、共享锁;</a></li><li><a href="#乐观锁的业务场景及实现方式">乐观锁的业务场景及实现方式;</a></li><li><a href="#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交">事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</a></li><li><a href="#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么">MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</a></li><li><a href="#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁">MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</a></li><li><a href="#分布式事务的原理2阶段提交-同步异步阻塞非阻塞">分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</a></li><li><a href="#数据库事务隔离级别-mysql默认的隔离级别">数据库事务隔离级别，MySQL默认的隔离级别;</a></li><li><a href="#spring如何实现事务">Spring如何实现事务;</a></li><li><a href="#jdbc如何实现事务">JDBC如何实现事务;</a></li><li><a href="#嵌套事务实现">嵌套事务实现；</a></li><li><a href="#分布式事务实现">分布式事务实现;</a></li><li><a href="#sql的整个解析、执行过程原理、sql行转列">SQL的整个解析、执行过程原理、SQL行转列;</a></li></ul></li></ul></div><p></p> <h2 id="jvm"><a href="#jvm" class="header-anchor">#</a> JVM</h2> <h3 id="jvm内存模型-gc机制和原理"><a href="#jvm内存模型-gc机制和原理" class="header-anchor">#</a> JVM内存模型，GC机制和原理;</h3> <p><strong>内存模型</strong></p> <p><code>Jdk1.6</code> 及之前:有永久代, 常量池在方法区</p> <p><code>Jdk1.7</code> 有永久代，但已经逐步“去永久代”，常量池在堆</p> <p><code>Jdk1.8</code> 及之后: 无永久代，常量池在元空间</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327094415.png" loading="lazy" class="lazy"></p> <h3 id="gc分哪两种-minor-gc-和full-gc有什么区别-什么时候会触发full-gc-分别采用什么算法"><a href="#gc分哪两种-minor-gc-和full-gc有什么区别-什么时候会触发full-gc-分别采用什么算法" class="header-anchor">#</a> GC分哪两种，Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?</h3> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327100327.png" loading="lazy" class="lazy"></p> <p>对象从新生代区域消失的过程，我们称之为 &quot;minor GC&quot;</p> <p>对象从老年代区域消失的过程，我们称之为 &quot;major GC&quot;</p> <p><strong>Minor GC</strong></p> <p>清理整个YouGen的过程，eden的清理，S0\S1的清理都会由于MinorGC Allocation Failure(YoungGen区内存不足)，而触发minorGC , Major GC OldGen区内存不足，触发Major GC</p> <p><strong>Full GC</strong></p> <p>Full GC 是清理整个堆空间—包括年轻代和永久代</p> <p>Full GC 触发的场景</p> <ol><li><p>System.gc</p></li> <li><p>promotion failed (年代晋升失败,比如eden区的存活对象晋升到S区放不下，又尝试直接晋 升到Old区又放不下，那么Promotion Failed,会触发FullGC)</p></li> <li><p>CMS的Concurrent-Mode-Failure</p> <p>由于CMS回收过程中主要分为四步:1.CMS initial mark 2.CMS Concurrent mark 3.CMS remark 4.CMS Concurrent sweep。在2中gc线程与用户线程同时执行，那么用户线程依旧可 能同时产生垃圾， 如果这个垃圾较多无法放入预留的空间就会产生CMS-Mode-Failure， 切换 为SerialOld单线程做mark-sweep-compact。</p></li> <li><p>新生代晋升的平均大小大于老年代的剩余空间 (为了避免新生代晋升到老年代失败) 当使用G1,CMS 时，FullGC发生的时候 是 Serial+SerialOld。 当使用ParalOld时，FullGC发生的时候是 ParallNew +ParallOld.</p></li></ol> <h3 id="jvm里的有几种classloader-为什么会有多种"><a href="#jvm里的有几种classloader-为什么会有多种" class="header-anchor">#</a> JVM里的有几种classloader，为什么会有多种?</h3> <p>启动类加载器:负责加载JRE的核心类库，如jre目标下的rt.jar,charsets.jar等</p> <p>扩展类加载器:负责加载JRE扩展目录ext中JAR类包</p> <p>系统类加载器:负责加载ClassPath路径下的类包</p> <p>用户自定义加载器:负责加载用户自定义路径下的类包</p> <p><strong>为什么会有多种:</strong></p> <ol><li>分工，各自负责各自的区块</li> <li>为了实现委托模型</li></ol> <h3 id="什么是双亲委派机制-介绍一些运作过程-双亲委派模型的好处"><a href="#什么是双亲委派机制-介绍一些运作过程-双亲委派模型的好处" class="header-anchor">#</a> 什么是双亲委派机制?介绍一些运作过程，双亲委派模型的好处;</h3> <p>如果一个类加载器收到了类加载请求，它并不会自己先去加载，而是把这个请求委托给父类的 加载器去执行，如果父类加载器还存在其父类加载器，则进一步向上委托，依次递归，请求最终 将到达顶层的启动类加载器，如果父类加载器可以完成类加载任务，就成功返回，倘若父类加载 器无法完成此加载任务，子加载器才会尝试自己去加载，这就是双亲委派模式，即每个儿子都不 愿意干活，每次有活就丢给父亲去干，直到父亲说这件事我也干不了时，儿子自己想办法去完 成，这不就是传说中的双亲委派模式。</p> <p><strong>动作过程</strong></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327100633.png" loading="lazy" class="lazy"></p> <p><strong>好处</strong></p> <p>沙箱安全机制: 自己写的String.class类不会被加载，这样便可以防止核心API库被随意篡改</p> <p>避免类的重复加载: 当父亲已经加载了该类时，就没有必要子ClassLoader再加载一次</p> <h3 id="什么情况下我们需要破坏双亲委派模型"><a href="#什么情况下我们需要破坏双亲委派模型" class="header-anchor">#</a> 什么情况下我们需要破坏双亲委派模型;</h3> <p>tomcat多应用并存加载</p> <h3 id="常见的jvm调优方法有哪些-可以具体到调整哪个参数-调成什么值"><a href="#常见的jvm调优方法有哪些-可以具体到调整哪个参数-调成什么值" class="header-anchor">#</a> 常见的JVM调优方法有哪些?可以具体到调整哪个参数，调成什么值?</h3> <p><strong>调优工具</strong></p> <p>console，jProfile，VisualVM</p> <p>Dump线程详细信息:查看线程内部运行情况</p> <p>死锁检查</p> <p>查看堆内类、对象信息查看:数量、类型等</p> <p><strong>线程监控</strong></p> <p>线程信息监控: 系统线程数量。
线程状态监控: 各个线程都处在什么样的状态下</p> <p><strong>热点分析</strong>
CPU热点: 检查系统哪些方法占用的大量CPU时间</p> <p>内存热点: 检查哪些对象在系统中数量最大(一定时间内存活对象和销毁对象一起统计)</p> <p><strong>内存泄漏检查</strong></p> <p>&lt;待补充&gt;</p> <h3 id="jvm虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的"><a href="#jvm虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的" class="header-anchor">#</a> JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;</h3> <p>JVM虚拟机内存划分(重复)</p> <p>类加载器(重复)</p> <p>垃圾收集算法:标记-清除算法、复制算法、标记-整理算法、分代收集算法</p> <p>垃圾收集器: Serial收集器、ParNew收集器、Parallel Scavenge收集器、Serial Old收集器、
Parallel Old收集器、CMS收集器、G1收集器、Z垃圾收集器</p> <p><strong>class文件结构是如何解析的</strong></p> <p>解悉过程:https://blog.csdn.net/sinat_38259539/article/details/78248454</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327105842.png" loading="lazy" class="lazy"></p> <h2 id="java基础、java进阶"><a href="#java基础、java进阶" class="header-anchor">#</a> Java基础、Java进阶</h2> <h3 id="红黑树的实现原理和应用场景"><a href="#红黑树的实现原理和应用场景" class="header-anchor">#</a> 红黑树的实现原理和应用场景;</h3> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327105918.png" loading="lazy" class="lazy"></p> <p>红黑树(一棵自平衡的排序二叉树)五大特性:</p> <ol><li>每个结点要么是红的，要么是黑的。</li> <li>根结点是黑的。</li> <li>每个叶结点，即空结点是黑的。</li> <li>如果一个结点是红的，那么它的俩个儿子都是黑的。</li> <li>对每个结点，从该结点到其子孙结点的所有路径上包含相同数目的黑结点。</li></ol> <p><strong>场景</strong></p> <ol><li>广泛用于 <code>C++</code> 的STL中，<code>map</code> 和 <code>set</code> 都是用红黑树实现的。</li> <li>著名的 <code>linux</code> 进程调度<code>Completely Fair Scheduler</code>,用红黑树管理进程控制块,进程的虚拟内存 区域都存储在一颗红黑树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址 虚拟存储区域,右指针指向相邻的高地址虚拟地址空间.</li> <li><code>IO</code> 多路复用epoll的实现采用红黑树组织管理 <code>sockfd</code> ，以支持快速的增删改查.</li> <li><code>ngnix</code> 中,用红黑树管理 <code>timer</code> ,因为红黑树是有序的,可以很快的得到距离当前最小的定时器.</li> <li><code>java</code> 中的 <code>TreeSet</code> , <code>TreeMap</code></li></ol> <h3 id="nio是什么-适用于何种场景"><a href="#nio是什么-适用于何种场景" class="header-anchor">#</a> NIO是什么?适用于何种场景?</h3> <p>(<code>New IO</code>) 为所有的原始类型( <code>boolean</code> 类型除外)提供缓存支持的数据容器，使用它可以提 供非阻塞式的高伸缩性网络。</p> <p>特性:<code>I/O</code> 多路复用 + 非阻塞式 <code>I/O</code></p> <p><code>NIO</code> 适用场景 服务器需要支持超大量的长时间连接。比如 10000 个连接以上，并且每个客户端并不会频繁地发 送太多数据。例如总公司的一个中心服务器需要收集全国便利店各个收银机的交易信息，只需要 少量线程按需处理维护的大量长期连接。</p> <p><code>Jetty</code>、<code>Mina</code>、<code>Netty</code>、<code>ZooKeeper</code> 等都是基于 <code>NIO</code> 方式实现。</p> <p><a href="http://www.ideabuffer.cn/2017/08/13/NIO%E6%8A%80%E6%9C%AF%E6%A6%82%E8%A7%88/" target="_blank" rel="noopener noreferrer">【NIO技术概览】<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h3 id="java9比java8改进了什么"><a href="#java9比java8改进了什么" class="header-anchor">#</a> Java9比Java8改进了什么;</h3> <ol><li><p>引入了模块系统，采用模块化系统的应用程序只需要这些应用程序所需的那部分JDK模块， 而非是整个JDK框架了，减少了内存的开销。</p></li> <li><p>引入了一个新的package:java.net.http，里面提供了对Http访问很好的支持，不仅支持 Http1.1而且还支持HTTP2。</p></li> <li><p>引入了jshell这个交互性工具，让Java也可以像脚本语言一样来运行，可以从控制台启动 jshell ，在 jshell 中直接输入表达式并查看其执行结果。</p></li> <li><p>增加了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法来创建不可变集合</p></li> <li><p>HTML5风格的Java帮助文档</p></li> <li><p>多版本兼容 JAR 功能，能让你创建仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本。</p></li> <li><p>统一 JVM 日志</p> <p>可以使用新的命令行选项-Xlog 来控制JVM 上 所有组件的日志记录。该日志记录系统可以设置</p></li> <li><p>垃圾收集机制</p> <p>Java 9 移除了在 Java 8 中 被废弃的垃圾回收器配置组合，同时把G1设为默认的垃圾回收器实 现.因为相对于Parallel来说，G1会在应用线程上做更多的事情，而Parallel几乎没有在应用线程 上做任何事情，它基本上完全依赖GC线程完成所有的内存管理。这意味着切换到G1将会为应用 线程带来额外的工作，从而直接影响到应用的性能</p></li> <li><p><code>I/O</code> 流新特性</p> <p>java.io.InputStream 中增加了新的方法来读取和复制 InputStream 中包含的数据。 readAllBytes:读取 InputStream 中的所有剩余字节。
readNBytes: 从 InputStream 中读取指定数量的字节到数组中。 transferTo:读取 InputStream 中的全部字节并写入到指定的 OutputStream 中 。</p></li></ol> <p>参考:
<a href="https://www.jb51.net/article/48304.htm" target="_blank" rel="noopener noreferrer"><code>java8</code> 新特性<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://blog.csdn.net/mxw2552261/article/details/79080678" target="_blank" rel="noopener noreferrer"><code>java9</code> 新特性<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h3 id="hashmap内部的数据结构是什么-底层是怎么实现的"><a href="#hashmap内部的数据结构是什么-底层是怎么实现的" class="header-anchor">#</a> HashMap内部的数据结构是什么?底层是怎么实现的?</h3> <p>HashMap内部结构</p> <p>jdk8以前:数组+链表</p> <p>jdk8以后:数组+链表 (当链表长度到8时，转化为红黑树)</p> <p>在并发的情况，发生扩容时，可能会产生循环链表，在执行get的时候，会触发死循环，引起 CPU的100%问题，所以一定要避免在并发环境下使用HashMap。</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327113525.png" loading="lazy" class="lazy"></p> <p><strong>延伸考察ConcurrentHashMap与HashMap、HashTable等，考察 对技术细节的深入了解程度;</strong></p> <p>HashMap、HashTable、ConcurrentHashMap的原理与区别</p> <p><a href="https://www.jianshu.com/p/1e9cf0ac07f4" target="_blank" rel="noopener noreferrer">老生常谈，HashMap的死循环<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://www.cnblogs.com/everSeeker/p/5601861.html" target="_blank" rel="noopener noreferrer">ConcurrentHashMap在jdk1.8中的改进<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://www.cnblogs.com/everSeeker/p/5601861.html" target="_blank" rel="noopener noreferrer">谈谈ConcurrentHashMap1.7和1.8的不同实现<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://www.jianshu.com/p/f6730d5784ad" target="_blank" rel="noopener noreferrer">深入分析ConcurrentHashMap1.8的扩容实现<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://www.jianshu.com/p/c0642afe03e0" target="_blank" rel="noopener noreferrer">深入浅出ConcurrentHashMap1.8<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://www.jianshu.com/p/23b84ba9a498" target="_blank" rel="noopener noreferrer">ConcurrentHashMap的红黑树实现分析<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h3 id="说说反射的用途及实现-反射是不是很慢-我们在项目中是否要避免使用反射"><a href="#说说反射的用途及实现-反射是不是很慢-我们在项目中是否要避免使用反射" class="header-anchor">#</a> 说说反射的用途及实现，反射是不是很慢，我们在项目中是否要避免使用反射;</h3> <p><strong>一、用途</strong></p> <p>反射被广泛地用于那些需要在运行时检测或修改程序行为的程序中。</p> <p><strong>二、实现方式</strong></p> <p>Foo foo = new Foo();</p> <p>第一种:通过Object类的getClass方法 Class cla = foo.getClass();</p> <p>第二种:通过对象实例方法获取对象
Class cla = foo.class;</p> <p>第三种:通过Class.forName方式</p> <p>Class cla = Class.forName(&quot;xx.xx.Foo&quot;);</p> <p><strong>三、缺点</strong></p> <ol><li><p>影响性能</p> <p>反射包括了一些动态类型，所以 JVM 无法对这些代码进行优化。因此，反射操作的效 率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程 序中使用反射。</p></li> <li><p>安全限制</p> <p>使用反射技术要求程序必须在一个没有安全限制的环境中运行。</p></li> <li><p>内部暴露</p> <p>由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方 法)，所以 使用反射可能会导致意料之外的副作用--代码有功能上的错误，降低可移植性。 反射代码破坏 了抽象性，因此当平台发生改变的时候，代码的行为就有可能也随着变化。</p></li></ol> <h3 id="说说自定义注解的场景及实现"><a href="#说说自定义注解的场景及实现" class="header-anchor">#</a> 说说自定义注解的场景及实现;</h3> <p>利用自定义注解,结合SpringAOP可以完成权限控制、日志记录、统一异常处理、数字签名、数 据加解密等功能。</p> <p><strong>实现场景(API接口数据加解密)</strong></p> <ol><li>自定义一个注解，在需要加解密的方法上添加该注解</li> <li>配置SringAOP环绕通知</li> <li>截获方法入参并进行解密</li> <li>截获方法返回值并进行加密</li></ol> <h3 id="list-和-map-区别"><a href="#list-和-map-区别" class="header-anchor">#</a> List 和 Map 区别</h3> <p><strong>一、概述</strong></p> <p>List是存储单列数据的集合，Map是存储键和值这样的双列数据的集合， List中存储的数据是有顺序，并且允许重复，值允许有多个null; Map中存储的数据是没有顺序的，键不能重复，值是可以有重复的，key最多有一个null。</p> <p><strong>二、明细</strong></p> <p><strong>List</strong></p> <ol><li>可以允许重复的对象。</li> <li>可以插入多个null元素。</li> <li>是一个有序容器，保持了每个元素的插入顺序，输出的顺序就是插入的顺序。</li> <li>常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行，它提供了使用索引 的随意访问，而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。</li></ol> <p><strong>Map</strong></p> <ol><li>Map不是collection的子接口或者实现类。Map是一个接口。</li> <li>Map 的 每个 Entry 都持有两个对象，也就是一个键一个值，Map 可能会持有相同的值对象 但键对象必须是唯一的。</li> <li>TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。</li> <li>Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。</li> <li>Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。 (HashMap、TreeMap最常用)</li></ol> <p><strong>Set(问题扩展)</strong></p> <ol><li>不允许重复对象</li> <li>无序容器，你无法保证每个元素的存储顺序，TreeSet通过 Comparator 或Comparable 维 护了一个排序顺序。</li> <li>只允许一个 null 元素</li> <li>Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口，因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。</li></ol> <p><strong>三、场景(问题扩展)</strong></p> <ol><li>如果你经常使用索引来对容器中的元素进行访问，那么 List 是你的正确的选择。如果你已 经知道索引了的话，那么 List 的实现类比如 ArrayList 可以提供更快速的访问,如果经常添加删除 元素的，那么肯定要选择LinkedList。</li> <li>如果你想容器中的元素能够按照它们插入的次序进行有序存储，那么还是 List，因为 List 是 一个有序容器，它按照插入顺序进行存储。</li> <li>如果你想保证插入元素的唯一性，也就是你不想有重复值的出现，那么可以选择一个 Set 的 实现类，比如 HashSet、LinkedHashSet 或者 TreeSet。所有 Set 的实现类都遵循了统一约束 比如唯一性，而且还提供了额外的特性比如 TreeSet 还是一个 SortedSet，所有存储于 TreeSet 中的元素可以使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet 也按 照元素的插入顺序对它们进行存储。</li> <li>如果你以键和值的形式进行数据存储那么 Map 是你正确的选择。你可以根据你的后续需要 从 Hashtable、HashMap、TreeMap 中进行选择。</li></ol> <p>参考:<a href="https://www.cnblogs.com/IvesHe/p/6108933.html" target="_blank" rel="noopener noreferrer">List、Set、Map的区别<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h3 id="arraylist-与-linkedlist-区别-arraylist-与-vector-区别"><a href="#arraylist-与-linkedlist-区别-arraylist-与-vector-区别" class="header-anchor">#</a> Arraylist 与 LinkedList 区别，ArrayList 与 Vector 区别;</h3> <ol><li><p>数据结构</p> <p>Vector、ArrayList内部使用数组，而LinkedList内部使用双向链表，由数组和链表的特性知: LinkedList适合指定位置插入、删除操作，不适合查找; ArrayList、Vector适合查找，不适合指定位置的插入删除操作。 但是ArrayList越靠近尾部的元素进行增删时，其实效率比LinkedList要高</p></li> <li><p>线程安全</p> <p>Vector线程安全，ArrayList、LinkedList线程不安全。</p></li> <li><p>空间</p></li></ol> <p>ArrayList在元素填满容器时会自动扩充容器大小的50%，而Vector则是100%，因此ArrayList更 节省空间。</p> <p>参考:ArrayList和LinkedList内部实现、区别、使用场景</p> <h2 id="多线程并发"><a href="#多线程并发" class="header-anchor">#</a> 多线程并发</h2> <h3 id="线程池的原理-为什么要创建线程池-创建线程池的方式"><a href="#线程池的原理-为什么要创建线程池-创建线程池的方式" class="header-anchor">#</a> 线程池的原理，为什么要创建线程池?创建线程池的方式;</h3> <p><strong>原理:</strong></p> <p><a href="https://www.cnblogs.com/dongguacai/p/6030187.html" target="_blank" rel="noopener noreferrer">JAVA线程池原理详解一<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://www.cnblogs.com/dongguacai/p/6038960.html" target="_blank" rel="noopener noreferrer">JAVA线程池原理详解二<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p>创建线程池的几种方式: <code>ThreadPoolExecutor</code>、<code>ThreadScheduledExecutor</code>、<code>ForkJoinPool</code></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220326235020.png" loading="lazy" class="lazy"></p> <h3 id="线程的生命周期-什么时候会出现僵死进程"><a href="#线程的生命周期-什么时候会出现僵死进程" class="header-anchor">#</a> 线程的生命周期，什么时候会出现僵死进程;</h3> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220326235100.png" loading="lazy" class="lazy">
僵死进程是指子进程退出时，父进程并未对其发出的 <code>SIGCHLD</code> 信号进行适当处理，导致子进程停留在僵死状态等待其父进程为其收尸，这个状态下的子进程就是僵死进程。</p> <h3 id="说说线程安全问题-什么实现线程安全-如何实现线程安全"><a href="#说说线程安全问题-什么实现线程安全-如何实现线程安全" class="header-anchor">#</a> 说说线程安全问题，什么实现线程安全，如何实现线程安全;</h3> <p>线程安全 - 如果线程执行过程中不会产生共享资源的冲突，则线程安全。</p> <p>线程不安全 - 如果有多个线程同时在操作主内存中的变量，则线程不安全</p> <p>实现线程安全的三种方式</p> <ol><li>互斥同步
<ul><li>临界区 <code>syncronized</code>、<code>ReentrantLock</code></li> <li>信号量 semaphore</li> <li>互斥量 mutex</li></ul></li> <li>非阻塞同步
<ul><li><code>CAS(Compare And Swap)</code></li></ul></li> <li>无同步方案
<ul><li>可重入代码：使用Threadlocal 类来包装共享变量，做到每个线程有自己的copy</li> <li>线程本地存储 参考:<code>https://blog.csdn.net/jackieeecheng/article/details/69779824</code></li></ul></li></ol> <h3 id="创建线程池有哪几个核心参数-如何合理配置线程池的大小"><a href="#创建线程池有哪几个核心参数-如何合理配置线程池的大小" class="header-anchor">#</a> 创建线程池有哪几个核心参数? 如何合理配置线程池的大小?</h3> <ol><li>核心参数</li></ol> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token class-name">ThreadPoolExecutor</span><span class="token punctuation">(</span><span class="token keyword">int</span> corePoolSize<span class="token punctuation">,</span> <span class="token comment">// 核心线程数量大小</span>
        <span class="token keyword">int</span> maximumPoolSize<span class="token punctuation">,</span> <span class="token comment">// 线程池最大容纳线程数 long keepAliveTime, // 线程空闲后的存活时长 TimeUnit unit,</span>
<span class="token comment">//缓存异步任务的队列 //用来构造线程池里的worker线程</span>
        <span class="token class-name">BlockingQueue</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Runnable</span><span class="token punctuation">&gt;</span></span> workQueue<span class="token punctuation">,</span>
        <span class="token class-name">ThreadFactory</span> threadFactory<span class="token punctuation">,</span>
<span class="token comment">//线程池任务满载后采取的任务拒绝策略</span>
        <span class="token class-name">RejectedExecutionHandler</span> handler<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><ol start="2"><li><p>核心说明</p> <ul><li>当线程池中线程数量小于 corePoolSize 则创建线程，并处理请求。</li> <li>当线程池中线程数量大于等于 corePoolSize 时，则把请求放入 workQueue 中,随着线程池 中的核心线程们不断执行任务，只要线程池中有空闲的核心线程，线程池就从 workQueue 中取 任务并处理。</li> <li>当 workQueue 已存满，放不下新任务时则新建非核心线程入池，并处理请求直到线程数目 达到 maximumPoolSize(最大线程数量设置值)。</li> <li>如果线程池中线程数大于 maximumPoolSize 则使用 RejectedExecutionHandler 来进行任 务拒绝处理。
参考：http://gudong.name/2017/05/03/thread-pool-intro.html</li></ul></li> <li><p>线程池大小分配</p> <p>线程池究竟设置多大要看你的线程池执行的什么任务了，CPU密集型、IO密集型、混合型，任 务类型不同，设置的方式也不一样。 任务一般分为:CPU密集型、IO密集型、混合型，对于不同类型的任务需要分配不同大小的线程池。</p> <ul><li>CPU密集型</li></ul> <p>尽量使用较小的线程池，一般Cpu核心数+1</p> <ul><li>IO密集型</li></ul> <p>方法一:可以使用较大的线程池，一般CPU核心数 * 2 方法二:(线程等待时间与线程CPU时间之比 + 1)* CPU数目</p> <ul><li><p>混合型</p> <p>可以将任务分为CPU密集型和IO密集型，然后分别使用不同的线程池去处理，按情况而定</p> <p>参考:https://www.cnblogs.com/cherish010/p/8334952.html</p></li></ul></li></ol> <h3 id="volatile、threadlocal的使用场景和原理"><a href="#volatile、threadlocal的使用场景和原理" class="header-anchor">#</a> volatile、ThreadLocal的使用场景和原理;</h3> <p><strong>volatile原理</strong></p> <p>volatile变量进行写操作时，JVM 会向处理器发送一条 Lock 前缀的指令，将这个变量所在缓 存行的数据写会到系统内存。</p> <p>Lock 前缀指令实际上相当于一个内存屏障(也成内存栅栏)，它确保指令重排序时不会把其 后面的指令排到内存屏障之前的位置，也不会把前面的指令排到内存屏障的后面;即在执行到内 存屏障这句指令时，在它前面的操作已经全部完成。</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327003309.png" loading="lazy" class="lazy"></p> <p><strong><code>volatile</code> 的适用场景</strong></p> <ol><li>状态标志,如:初始化或请求停机</li> <li>一次性安全发布，如:单列模式</li> <li>独立观察，如:定期更新某个值</li> <li>“<code>volatile bean</code>” 模式</li> <li>开销较低的“读-写锁”策略，如:计数器</li></ol> <p>参考:https://blog.csdn.net/hgc0907/article/details/79664102</p> <p>参考:https://www.ibm.com/developerworks/cn/java/j-jtp06197.html</p> <p><strong><code>ThreadLocal</code> 原理</strong></p> <p><code>ThreadLocal</code> 是用来维护本线程的变量的，并不能解决共享变量的并发问题。<code>ThreadLocal</code> 是各线程将值存入该线程的map中，以ThreadLocal自身作为key，需要用时获得的是该线程之前 存入的值。如果存入的是共享变量，那取出的也是共享变量，并发问题还是存在的。</p> <p>参考:https://www.jianshu.com/p/ee8c9dccc953</p> <p>参考:https://blog.csdn.net/xlgen157387/article/details/78297568</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327003558.png" loading="lazy" class="lazy"></p> <p><strong><code>ThreadLocal</code> 的适用场景</strong></p> <p>场景:数据库连接、<code>Session</code> 管理、</p> <p>参考:<code>https://www.jianshu.com/p/cadd53f063b9</code></p> <h3 id="threadlocal-什么时候会出现oom的情况-为什么"><a href="#threadlocal-什么时候会出现oom的情况-为什么" class="header-anchor">#</a> ThreadLocal 什么时候会出现OOM的情况?为什么?</h3> <p><code>ThreadLocal</code> 变量是维护在 <code>Thread</code> 内部的，这样的话只要我们的线程不退出，对象的引用就会 一直存在。当线程退出时，<code>Thread</code> 类会进行一些清理工作，其中就包含 <code>ThreadLocalMap</code> ， <code>Thread</code> 调用 <code>exit</code> 方法如下:</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220327005127.png" loading="lazy" class="lazy"></p> <p><code>ThreadLocal</code> 在没有线程池使用的情况下，正常情况下不会存在内存泄露，但是如果使用了线程 池的话，就依赖于线程池的实现，如果线程池不销毁线程的话，那么就会存在内存泄露。</p> <p>参考:https://blog.csdn.net/xlgen157387/article/details/78297568</p> <h3 id="synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性"><a href="#synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性" class="header-anchor">#</a> synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;</h3> <ol><li><code>volatile</code> 主要应用在多个线程对实例变量更改的场合，刷新主内存共享变量的值从而使得各个 线程可以获得最新的值，线程读取变量的值需要从主存中读取; <code>synchronized</code> 则是锁定当前变 量，只有当前线程可以访问该变量，其他线程被阻塞住。另外，<code>synchronized</code> 还会创建一个内 存屏障，内存屏障指令保证了所有CPU操作结果都会直接刷到主存中(即释放锁前)，从而保证 了操作的内存可见性，同时也使得先获得这个锁的线程的所有操作</li> <li><code>volatile</code> 仅能使用在变量级别;<code>synchronized</code> 则可以使用在变量、方法、和类级别的。 <code>volatile</code> 不会造成线程的阻塞; <code>synchronized</code> 可能会造成线程的阻塞，比如多个线程争抢 <code>synchronized</code> 锁对象时，会出现阻塞。</li> <li><code>volatile</code> 仅能实现变量的修改可见性，不能保证原子性;而 <code>synchronized</code> 则可以保证变量的 修改可见性和原子性，因为线程获得锁才能进入临界区，从而保证临界区中的所有语句全部得到 执行。</li> <li><code>volatile</code> 标记的变量不会被编译器优化，可以禁止进行指令重排;<code>synchronized</code> 标记的变量 可以被编译器优化。</li></ol> <p>参考: https://blog.csdn.net/xiaoming100001/article/details/79781680</p> <p><strong>synchronized锁粒度、模拟死锁场景;</strong></p> <p>synchronized : 具有原子性，有序性和可见性</p> <p>参考: <code>https://www.jianshu.com/p/cf57726e77f2</code></p> <p>粒度:对象锁、类锁</p> <p>死锁场景，参考: <code>https://blog.csdn.net/u013925989/article/details/50208839</code></p> <h2 id="spring"><a href="#spring" class="header-anchor">#</a> Spring</h2> <h3 id="spring-aop的实现原理和场景"><a href="#spring-aop的实现原理和场景" class="header-anchor">#</a> Spring AOP的实现原理和场景?</h3> <p>AOP(Aspect Orient Programming)，作为面向对象编程的一种补充，广泛应用于处理一 些具有横切性质的系统级服务。</p> <p><strong>一、场景</strong></p> <p>事务管理、安全检查、权限控制、数据校验、缓存、对象池管理等</p> <p><strong>二、实现技术</strong></p> <p>AOP(这里的AOP指的是面向切面编程思想，而不是Spring AOP)主要的的实现技术主要有 Spring AOP和AspectJ。</p> <ol><li><p>AspectJ的底层技术。</p> <p>AspectJ的底层技术是静态代理，即用一种AspectJ支持的特定语言编写切面，通过一个命令来 编译，生成一个新的代理类，该代理类增强了业务类，这是在编译时增强，相对于下面说的运行 时增强，编译时增强的性能更好。</p></li> <li><p>Spring AOP</p> <p>Spring AOP采用的是动态代理，在运行期间对业务方法进行增强，所以不会生成新类，对于
动态代理技术，Spring AOP提供了对JDK动态代理的支持以及CGLib的支持。 JDK动态代理只能为接口创建动态代理实例，而不能对类创建动态代理。需要获得被目标类的 接口信息(应用Java的反射技术)，生成一个实现了代理接口的动态代理类(字节码)，再通过 反射机制获得动态代理类的构造函数，利用构造函数生成动态代理类的实例对象，在调用具体方
法前调用invokeHandler方法来处理。</p> <p>CGLib动态代理需要依赖asm包，把被代理对象类的class文件加载进来，修改其字节码生成
子类。</p> <p>但是Spring AOP基于注解配置的情况下，需要依赖于AspectJ包的标准注解。</p></li></ol> <h3 id="spring-bean的作用域和生命周期"><a href="#spring-bean的作用域和生命周期" class="header-anchor">#</a> Spring bean的作用域和生命周期;</h3> <p><strong>作用域</strong></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327155248.png" loading="lazy" class="lazy"></p> <p><strong>生命周期</strong></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327155700.png" loading="lazy" class="lazy"></p> <h3 id="spring-boot比spring做了哪些改进"><a href="#spring-boot比spring做了哪些改进" class="header-anchor">#</a> Spring Boot比Spring做了哪些改进?</h3> <ol><li>Spring Boot可以建立独立的Spring应用程序;</li> <li>内嵌了如Tomcat，Jetty和Undertow这样的容器，也就是说可以直接跑起来，用不着再做 部署工作了;</li> <li>无需再像Spring那样搞一堆繁琐的xml文件的配置;</li> <li>可以自动配置Spring。SpringBoot将原有的XML配置改为Java配置，将bean注入改为使 用注解注入的方式(@Autowire)，并将多个xml、properties配置浓缩在一个application.yml 配置文件中。</li> <li>提供了一些现有的功能，如量度工具，表单数据验证以及一些外部配置这样的一些第三方功 能;</li> <li>整合常用依赖(开发库，例如spring-webmvc、jackson-json、validation-api和tomcat 等)，提供的POM可以简化Maven的配置。当我们引入核心依赖时，SpringBoot会自引入其 他依赖。</li></ol> <h3 id="spring-5比spring4做了哪些改进"><a href="#spring-5比spring4做了哪些改进" class="header-anchor">#</a> Spring 5比Spring4做了哪些改进;</h3> <p><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/" target="_blank" rel="noopener noreferrer">【官网说明】<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> <strong>Spring 4.x 新特性</strong></p> <ol><li>泛型限定式依赖注入</li> <li>核心容器的改进</li> <li><code>web</code> 开发增强</li> <li>集成<code>Bean Validation 1.1(JSR-349)</code> 到 <code>SpringMVC</code></li> <li><code>Groovy Bean</code> 定义 <code>DSL</code></li> <li>更好的 <code>Java</code> 泛型操作 <code>API</code></li> <li><code>JSR310</code> 日期API的支持</li> <li>注解、脚本、任务、<code>MVC</code> 等其他特性改进</li></ol> <p><strong>Spring 5.x 新特性</strong></p> <ol><li><code>JDK8</code> 的增强</li> <li>核心容器的改进</li> <li>新的 <code>SpringWebFlux</code> 模块</li> <li>测试方面的改进</li></ol> <p><strong>参考:</strong></p> <p><a href="http://ifeve.com/spring-5-new/" target="_blank" rel="noopener noreferrer">[Spring5 官方文档新功能]<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <ul><li>Spring4新特性——泛型限定式依赖注入</li> <li>Spring4新特性——核心容器的其他改进</li> <li>Spring4新特性——Web开发的增强</li> <li>Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC</li> <li>Spring4新特性——Groovy Bean定义DSL</li> <li>Spring4新特性——更好的Java泛型操作API Spring4新特性——JSR310日期API的支持</li> <li>Spring4新特性——注解、脚本、任务、MVC等其他特性改进</li></ul> <h3 id="如何自定义一个spring-boot-starter"><a href="#如何自定义一个spring-boot-starter" class="header-anchor">#</a> 如何自定义一个Spring Boot Starter?</h3> <p><a href="https://blog.csdn.net/boling_cavalry/article/details/82956512" target="_blank" rel="noopener noreferrer">《自定义spring boot starter三部曲之一:准备工作》;<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://blog.csdn.net/boling_cavalry/article/details/83041472" target="_blank" rel="noopener noreferrer">《自定义spring boot starter三部曲之二:实战开发》;<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://blog.csdn.net/boling_cavalry/article/details/83048588" target="_blank" rel="noopener noreferrer">《自定义spring boot starter三部曲之三:源码分析spring.factories加载过程》;<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h3 id="spring-ioc是什么-优点是什么"><a href="#spring-ioc是什么-优点是什么" class="header-anchor">#</a> Spring IOC是什么?优点是什么?</h3> <p>IoC 文英全称 Inversion of Control，即控制反转，我么可以这么理解IoC容器:“把某些业务对 象的的控制权交给一个平台或者框架来同一管理，这个同一管理的平台可以称为IoC容器。”</p> <p>ioc的思想最核心的地方在于，资源不由使用资源的双方管理，而由不使用资源的第三方管理， 这可以带来很多好处:</p> <ol><li>资源集中管理，实现资源的可配置和易管理</li> <li>降低了使用资源双方的依赖程度，也就是我们说的耦合度</li></ol> <p><a href="https://blog.csdn.net/he90227/article/details/51536348" target="_blank" rel="noopener noreferrer">Spring IOC原理解读 面试必读<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h3 id="springmvc、动态代理、反射、aop原理、事务隔离级别"><a href="#springmvc、动态代理、反射、aop原理、事务隔离级别" class="header-anchor">#</a> SpringMVC、动态代理、反射、AOP原理、事务隔离级别;</h3> <h4 id="springmvc"><a href="#springmvc" class="header-anchor">#</a> SpringMVC</h4> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327160450.png" loading="lazy" class="lazy"></p> <h4 id="动态代理-反射-aop原理-spring事务"><a href="#动态代理-反射-aop原理-spring事务" class="header-anchor">#</a> 动态代理 反射 AOP原理 Spring事务;</h4> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327160806.png" loading="lazy" class="lazy"></p> <p>一、spring事务</p> <p>什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.</p> <p>二、事务特性(4种):</p> <p>原子性 (atomicity): 强调事务的不可分割.
一致性 (consistency): 事务的执行的前后数据的完整性保持一致.
隔离性 (isolation): 一个事务执行的过程中,不应该受到其他事务的干扰
持久性(durability): 事务一旦结束,数据就持久到数据库</p> <p>如果不考虑隔离性引发安全性问题:</p> <p>脏读 : 一个事务读到了另一个事务的未提交的数据</p> <p>不可重复读 : 一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.</p> <p>虚幻读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致.</p> <p>三、解决读问题: 设置事务隔离级别(5种)</p> <p>DEFAULT 这是一个 PlatformTransactionManager 默认的隔离级别，使用数据库默认的事务隔 离级别.</p> <p>未提交读( <code>read uncommited</code> ) :脏读，不可重复读，虚读都有可能发生</p> <p>已提交读 ( <code>read commited</code> ):避免脏读。但是不可重复读和虚读有可能发生</p> <p>可重复读 ( <code>repeatable read</code> ) :避免脏读和不可重复读.但是虚读有可能发生.</p> <p>串行化的 ( <code>serializable</code> ) :避免以上所有读问题.</p> <p>Mysql 默认:可重复读</p> <p>Oracle 默认:读已提交</p> <p>四、事务的传播行为
PROPAGION_XXX :事务的传播行为</p> <ul><li><p>保证同一个事务中</p> <p>PROPAGATION_REQUIRED 支持当前事务，如果不存在 就新建一个(默认) PROPAGATION_SUPPORTS 支持当前事务，如果不存在，就不使用事务 PROPAGATION_MANDATORY 支持当前事务，如果不存在，抛出异常</p></li> <li><p>保证没有在同一个事务中</p> <p>PROPAGATION_REQUIRES_NEW 如果有事务存在，挂起当前事务，创建一个新的事务 PROPAGATION_NOT_SUPPORTED 以非事务方式运行，如果有事务存在，挂起当前事务 PROPAGATION_NEVER 以非事务方式运行，如果有事务存在，抛出异常 PROPAGATION_NESTED 如果当前事务存在，则嵌套事务执行</p></li></ul> <h2 id="框架-中间件"><a href="#框架-中间件" class="header-anchor">#</a> 框架|中间件</h2> <h3 id="redis"><a href="#redis" class="header-anchor">#</a> Redis</h3> <h4 id="redis-为什么这么快"><a href="#redis-为什么这么快" class="header-anchor">#</a> Redis 为什么这么快?</h4> <ol><li>绝大部分请求是纯粹的内存操作(非常快速)</li> <li>采用单线程,避免了不必要的上下文切换和竞争条件</li> <li>非阻塞IO - IO多路复用</li></ol> <h4 id="redis采用多线程会有哪些问题"><a href="#redis采用多线程会有哪些问题" class="header-anchor">#</a> redis采用多线程会有哪些问题?</h4> <ol><li>单线程的问题</li></ol> <p>无法发挥多核CPU性能，单进程单线程只能跑满一个CPU核 可以通过在单机开多个Redis实例来完善 可以通过数据分片来增加吞吐量，问题(不支持批量操作、扩缩容复杂等)</p> <ol start="2"><li>多线程的问题</li></ol> <p>多线程处理可能涉及到锁 多线程处理会涉及到线程切换而消耗CPU</p> <p>参考:<a href="https://www.sohu.com/a/251107445_100253472" target="_blank" rel="noopener noreferrer">阿里云Redis多线程性能提升思路解析<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h4 id="redis-支持哪几种数据结构"><a href="#redis-支持哪几种数据结构" class="header-anchor">#</a> Redis 支持哪几种数据结构?</h4> <p>String 、List 、Set 、Hash 、ZSet</p> <h4 id="redis-跳表"><a href="#redis-跳表" class="header-anchor">#</a> Redis 跳表</h4> <p>Redis只在两个地方用到了跳跃表，一个是实现有序集合键，另一个是在集群结点中用作内部数据结构</p> <p>参考:https://blog.csdn.net/idwtwt/article/details/80233859</p> <h4 id="redis单进程单线程的redis如何能够高并发"><a href="#redis单进程单线程的redis如何能够高并发" class="header-anchor">#</a> Redis单进程单线程的Redis如何能够高并发?</h4> <p>采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消 耗)</p> <h4 id="redis如何使用redis实现分布式锁"><a href="#redis如何使用redis实现分布式锁" class="header-anchor">#</a> Redis如何使用Redis实现分布式锁?</h4> <p>参考:<a href="https://www.cnblogs.com/linjiqin/p/8003838.html" target="_blank" rel="noopener noreferrer">Redis分布式锁的正确实现方式<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h4 id="redis分布式锁操作的原子性-redis内部是如何实现的"><a href="#redis分布式锁操作的原子性-redis内部是如何实现的" class="header-anchor">#</a> Redis分布式锁操作的原子性，Redis内部是如何实现的?</h4> <p>setnx</p> <p>Incrby\Decrby</p> <h3 id="dubbo"><a href="#dubbo" class="header-anchor">#</a> Dubbo</h3> <h4 id="dubbo完整的一次调用链路介绍"><a href="#dubbo完整的一次调用链路介绍" class="header-anchor">#</a> Dubbo完整的一次调用链路介绍;</h4> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327161739.png" loading="lazy" class="lazy">
参考:http://dubbo.apache.org/zh-cn/docs/dev/design.html</p> <h4 id="dubbo支持几种负载均衡策略"><a href="#dubbo支持几种负载均衡策略" class="header-anchor">#</a> Dubbo支持几种负载均衡策略?</h4> <ol><li><p>Random LoadBalance</p> <p>随机，按权重设置随机概率。 在一个截面上碰撞的概率高，但调用量越大分布越均匀，而且按概率使用权重后也比较均匀，有 利于动态调整提供者权重。</p></li> <li><p>RoundRobin LoadBalance</p> <p>轮询，按公约后的权重设置轮询比率。 存在慢的提供者累积请求的问题，比如:第二台机器很慢，但没挂，当请求调到第二台时就卡在 那，久而久之，所有请求都卡在调到第二台上。</p></li> <li><p>LeastActive LoadBalance</p> <p>最少活跃调用数，相同活跃数的随机，活跃数指调用前后计数差。 使慢的提供者收到更少请求，因为越慢的提供者的调用前后计数差会越大。</p></li> <li><p>ConsistentHash LoadBalance</p> <p>一致性 Hash，相同参数的请求总是发到同一提供者。 当某一台提供者挂时，原本发往该提供者的请求，基于虚拟节点，平摊到其它提供者，不会引起 剧烈变动。
算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
缺省只对第一个参数 Hash，如果要修改，请配置
&lt;dubbo:parameter key=&quot;hash.arguments&quot; value=&quot;0,1&quot; /&gt;
缺省用 160 份虚拟节点，如果要修改，请配置
&lt;dubbo:parameter key=&quot;hash.nodes&quot; value=&quot;320&quot; /&gt;</p> <p>参考:http://dubbo.apache.org/zh-cn/docs/user/demos/loadbalance.html</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327161959.png" loading="lazy" class="lazy">
源码分析: <code>http://www.cnblogs.com/wyq178/p/9822731.html</code></p></li></ol> <h4 id="dubbo-provider服务提供者要控制执行并发请求上限-具体怎么做"><a href="#dubbo-provider服务提供者要控制执行并发请求上限-具体怎么做" class="header-anchor">#</a> Dubbo Provider服务提供者要控制执行并发请求上限，具体怎么做?</h4> <p>服务端并发限流: executes</p> <p>客户端并发限流: actives</p> <p>样例1：
限制 com.foo.BarService 的每个方法，服务器端并发执行(或占用线程池线程数)不能超过 10 个。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span> <span class="token attr-name">executes</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>样例2：</p> <p>限制 <code>com.foo.BarService</code> 的 <code>sayHello</code> 方法，服务器端并发执行(或占用线程池线程数)不能超过 10 个。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span> <span class="token attr-name">executes</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>method</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>sayHello<span class="token punctuation">&quot;</span></span>  <span class="token attr-name">actives</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>service</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>样例 3</p> <p>限制 <code>com.foo.BarService</code> 的每个方法，每客户端并发执行(或占用连接的请求数)不能超过 10 个:</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>reference</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span> <span class="token attr-name">executes</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>service</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>样例 4
限制 <code>com.foo.BarService</code> 的 <code>sayHello</code> 方法，每客户端并发执行(或占用连接的请求数)不能 超过 10 个:</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>method</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>sayHello<span class="token punctuation">&quot;</span></span>  <span class="token attr-name">actives</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>service</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>或</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>reference</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>method</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>sayHello<span class="token punctuation">&quot;</span></span>  <span class="token attr-name">actives</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>reference</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>参考:http://dubbo.apache.org/zh-cn/docs/user/demos/concurrency-control.html</p> <h4 id="dubbo启动的时候支持几种配置方式"><a href="#dubbo启动的时候支持几种配置方式" class="header-anchor">#</a> Dubbo启动的时候支持几种配置方式?</h4> <p>XML配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/xml.html</p> <p>属性配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/properties.html</p> <p>API配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/api.html</p> <p>注解配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/annotation.html</p> <h3 id="spring-cloud"><a href="#spring-cloud" class="header-anchor">#</a> Spring Cloud</h3> <h4 id="spring-cloud熔断机制介绍"><a href="#spring-cloud熔断机制介绍" class="header-anchor">#</a> Spring Cloud熔断机制介绍;</h4> <p>在Spring Cloud框架里，熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况，当失 败的调用到一定阈值，缺省是5秒内20次调用失败，就会启动熔断机制。熔断机制的注解是 @HystrixCommand，Hystrix会找有这个注解的方法，并将这类方法关联到和熔断器连在一起 的代理上。当前，@HystrixCommand仅当类的注解为@Service或@Component时才会发挥 作用。</p> <h4 id="spring-cloud对比下dubbo-什么场景下该使用spring-cloud"><a href="#spring-cloud对比下dubbo-什么场景下该使用spring-cloud" class="header-anchor">#</a> Spring Cloud对比下Dubbo，什么场景下该使用Spring Cloud?</h4> <p>两者所解决的问题域不一样，Dubbo的定位始终是一款RPC框架，而Spring Cloud的目的是微服务架构下的一站式解决方案。</p> <p>Spring Cloud抛弃了Dubbo的RPC通信，采用的是基于HTTP的REST方式。 严格来说，这两种方式各有优劣。虽然在一定程度上来说，后者牺牲了服务调用的性能，但也避 免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活，服务提供方和调用方的依赖 只依靠一纸契约，不存在代码级别的强依赖，这在强调快速演化的微服务环境下，显得更为合 适。</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327171104.png" loading="lazy" class="lazy"></p> <p>更多对比: http://blog.51cto.com/13954634/2296010</p> <h3 id="消息队列"><a href="#消息队列" class="header-anchor">#</a> 消息队列</h3> <h4 id="了解几种消息中间件产品-各产品的优缺点介绍-消息中间件如何保证消息的一致性"><a href="#了解几种消息中间件产品-各产品的优缺点介绍-消息中间件如何保证消息的一致性" class="header-anchor">#</a> 了解几种消息中间件产品?各产品的优缺点介绍;消息中间件如何保证消息的一致性</h4> <ol><li><p>主动方应用先把消息发送给消息中间件，消息状态标记为待确认;</p></li> <li><p>消息中间件收到消息之后，把消息持久化到消息存储中，但并不向被动方应用投递消息;</p></li> <li><p>消息中间件返回消息持久化结果(成功，或者失效)，主动方应用根据返回结果进行判断如何</p> <p>处理业务操作处理;</p> <ul><li>失败:放弃业务操作处理，结束(必须向上层返回失败结果)</li> <li>成功:执行业务操作处理</li></ul></li> <li><p>业务操作完成后，把业务操作结果(成功/失败)发送给消息中间件;</p></li> <li><p>消息中间件收到业务操作结果后，根据结果进行处理</p> <ol><li>失败:删除消息存储中的消息，结束;</li> <li>成功:更新消息存储中的消息状态为∙待发送(可发送)∙，紧接着执行消息投递;</li></ol></li> <li><p>前面的正向流程都成功后，向被动方应用投递消息;</p></li></ol> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327164828.png" loading="lazy" class="lazy"></p> <h4 id="如何进行消息的重试机制"><a href="#如何进行消息的重试机制" class="header-anchor">#</a> 如何进行消息的重试机制?</h4> <p>参考:<a href="https://www.cnblogs.com/520playboy/p/6748680.html" target="_blank" rel="noopener noreferrer">Rocket重试机制，消息模式，刷盘方式<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h2 id="数据库"><a href="#数据库" class="header-anchor">#</a> 数据库</h2> <h3 id="锁机制介绍-行锁、表锁、排他锁、共享锁"><a href="#锁机制介绍-行锁、表锁、排他锁、共享锁" class="header-anchor">#</a> 锁机制介绍:行锁、表锁、排他锁、共享锁;</h3> <h3 id="乐观锁的业务场景及实现方式"><a href="#乐观锁的业务场景及实现方式" class="header-anchor">#</a> 乐观锁的业务场景及实现方式;</h3> <h3 id="事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交"><a href="#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交" class="header-anchor">#</a> 事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</h3> <h3 id="mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么"><a href="#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么" class="header-anchor">#</a> MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</h3> <p>mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR)，基于行 的复制(row-based replication, RBR)，混合模式复制(mixed-based replication, MBR)。对应 的，binlog的格式也有三种:STATEMENT，ROW，MIXED。
1 STATEMENT模式(SBR)</p> <p>每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的 数据变化，减少了binlog日志量，节约IO，提高性能。缺点是在某些情况下会导致master-slave 中的数据不一致( 如sleep()函数， last_insert_id()，以及user-defined functions(udf)等会出现 问题)
2 ROW模式(RBR)</p> <p>不记录每条 sql 语句的上下文信息，仅需记录哪条数据被修改了，修改成什么样了。而且不会出 现某些特定情况下的存储过程、或 function 、或 trigger 的调用和触发无法被正确复制的问题。缺 点是会产生大量的日志，尤其是 alter table 的时候会让日志暴涨。
3 MIXED模式(MBR)</p> <p>以上两种模式的混合使用，一般的复制使用 <code>STATEMENT</code> 模式保存 <code>binlog</code>，对于 <code>STATEMENT</code> 模式无法复制的操作使用 <code>ROW</code> 模式保存 <code>binlog</code>，MySQL 会根据执行的 SQL 语句选择日志保存方式。</p> <h3 id="mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁"><a href="#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁" class="header-anchor">#</a> MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</h3> <p>乐观锁</p> <p>用数据版本(Version)记录机制实现，这是乐观锁最常用的一种实现方式。何谓数据版本?即 为数据增加一个版本标识，一般是通过为数据库表增加一个数字类型的 “version” 字段来实 现。当读取数据时，将version字段的值一同读出，数据每更新一次，对此version值加1。当我 们提交更新的时候，判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比 对，如果数据库表当前版本号与第一次取出来的version值相等，则予以更新，否则认为是过期 数据。
悲观锁</p> <p>在进行每次操作时都要通过获取锁才能进行对相同数据的操作，这点跟java中synchronized很 相似，共享锁(读锁)和排它锁(写锁)是悲观锁的不同的实现</p> <p>共享锁(读锁)</p> <p>共享锁又叫做读锁，所有的事务只能对其进行读操作不能写操作，加上共享锁后在事务结束之前
其他事务只能再加共享锁，除此之外其他任何类型的锁都不能再加了。</p> <p>排它锁(写锁)</p> <p>若某个事物对某一行加上了排他锁，只能这个事务对其进行读写，在此事务结束之前，其他事务 不能对其进行加任何锁，其他进程可以读取,不能进行写操作，需等待其释放。</p> <p>表级锁</p> <p>innodb 的行锁是在有索引的情况下,没有索引的表是锁定全表的</p> <p>行级锁</p> <p>行锁又分共享锁和排他锁,由字面意思理解，就是给某一行加上锁，也就是一条记录加上锁。 注意:行级锁都是基于索引的，如果一条SQL语句用不到索引是不会使用行级锁的，会使用表级 锁。</p> <p>更多参考:https://blog.csdn.net/yzj5208/article/details/81288633</p> <h3 id="分布式事务的原理2阶段提交-同步异步阻塞非阻塞"><a href="#分布式事务的原理2阶段提交-同步异步阻塞非阻塞" class="header-anchor">#</a> 分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</h3> <h3 id="数据库事务隔离级别-mysql默认的隔离级别"><a href="#数据库事务隔离级别-mysql默认的隔离级别" class="header-anchor">#</a> 数据库事务隔离级别，MySQL默认的隔离级别;</h3> <p>Mysql默认隔离级别:Repeatable Read</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327165440.png" loading="lazy" class="lazy"></p> <h3 id="spring如何实现事务"><a href="#spring如何实现事务" class="header-anchor">#</a> Spring如何实现事务;</h3> <p><a href="https://www.cnblogs.com/yixianyixian/p/8372832.html" target="_blank" rel="noopener noreferrer">参考:spring事务管理(详解和实例)<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327165555.png" loading="lazy" class="lazy"></p> <p>Spring 事物四种实现方式:</p> <ul><li>基于编程式事务管理实现</li> <li>基于TransactionProxyFactoryBean的声明式事务管理</li> <li>基于AspectJ的XML声明式事务管理</li> <li>基于注解的声明式事务管理</li></ul> <p>参考:https://blog.csdn.net/zhuxinquan61/article/details/71075051</p> <h3 id="jdbc如何实现事务"><a href="#jdbc如何实现事务" class="header-anchor">#</a> JDBC如何实现事务;</h3> <p>在JDBC中处理事务，都是通过Connection完成的。</p> <p>同一事务中所有的操作，都在使用同一个Connection对象。</p> <ol><li><p>JDBC中的事务</p> <p>Connection的三个方法与事务有关:</p> <ul><li>setAutoCommit(boolean):设置是否为自动提交事务，如果true(默认值为true)表示自动提 交，也就是每条执行的SQL语句都是一个单独的事务，如果设置为false，那么相当于开启了事务了; con.setAutoCommit(false) 表示开启事务。</li> <li>commit():提交结束事务。</li> <li>rollback():回滚结束事务。</li></ul></li></ol> <p><strong>示例代码</strong></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">try</span><span class="token punctuation">{</span>    
        con<span class="token punctuation">.</span><span class="token function">setAutoCommit</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//开启事务</span>
        <span class="token comment">//......</span>
        con<span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//try的最后提交事务 </span>
         <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        con<span class="token punctuation">.</span><span class="token function">rollback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//回滚事务</span>
 <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h3 id="嵌套事务实现"><a href="#嵌套事务实现" class="header-anchor">#</a> 嵌套事务实现；</h3> <p>TODO</p> <h3 id="分布式事务实现"><a href="#分布式事务实现" class="header-anchor">#</a> 分布式事务实现;</h3> <ol><li><p>基于XA协议的两阶段提交(2PC)</p> <p>XA 规范主要 定义了 ( 全局 ) 事务管理器 ( Transaction Manager ) 和 ( 局部 ) 资源管理器 ( Resource Manager ) 之间的接口。</p></li> <li><p>两阶段提交</p> <p>事务的提交分为两个阶段: 预提交阶段(Pre-Commit Phase) 决策后阶段(Post-Decision Phase)</p></li> <li><p>补偿事务(TCC)</p> <p>针对每个操作，都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段
Try 阶段主要是对业务系统做检测及资源预留
Confirm 阶段主要是对业务系统做确认提交，Try 阶段执行成功并开始执行 Confirm 阶段时， 默认Confirm 阶段是不会出错的。即:只要 Try 成功，Confirm 一定成功。
Cancel 阶段主要是在业务执行错误，需要回滚的状态下执行的业务取消，预留资源释放</p></li> <li><p>本地消息表(MQ 异步确保)</p> <p>其基本的设计思想是将远程分布式事务拆分成一系列的本地事务。</p></li> <li><p>MQ 事务消息</p> <p>有一些第三方的 MQ 是支持事务消息的，比如 RocketMQ，他们支持事务消息的方式也是类似 于采用的二阶段提交，但是市面上一些主流的 MQ 都是不支持事务消息的，比如 RabbitMQ 和 Kafka 都不支持。</p></li> <li><p>Sagas 事务模型</p> <p>该模型其核心思想就是拆分分布式系统中的长事务为多个短事务，或者叫多个本地事务，然后由 Sagas 工作流引擎负责协调，如果整个流程正常结束，那么就算是业务成功完成，如果在这过程 中实现失败，那么Sagas工作流引擎就会以相反的顺序调用补偿操作，重新进行业务回滚。</p></li> <li><p>其他补偿方式</p> <p>加入详细日志记录的，一旦系统内部引发类似致命异常，会有邮件通知。同时，后台会有定时任 务扫描和分析此类日志，检查出这种特殊的情况，会尝试通过程序来补偿并邮件通知相关人员。 在某些特殊的情况下，还会有 &quot;人工补偿&quot; 的，这也是最后一道屏障。</p></li></ol> <p>参考: https://www.javazhiyin.com/573.html</p> <h3 id="sql的整个解析、执行过程原理、sql行转列"><a href="#sql的整个解析、执行过程原理、sql行转列" class="header-anchor">#</a> SQL的整个解析、执行过程原理、SQL行转列;</h3> <p><strong>整体架构</strong></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327170816.png" loading="lazy" class="lazy"></p> <p><strong>SQL解析</strong></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327170903.png" loading="lazy" class="lazy"></p> <p><strong>行转列、列转行</strong></p> <p>参考:https://blog.csdn.net/jx_870915876/article/details/52403472</p> <h4 id="redis-跳表-2"><a href="#redis-跳表-2" class="header-anchor">#</a> Redis 跳表</h4> <h4 id="redis单进程单线程的redis如何能够高并发-2"><a href="#redis单进程单线程的redis如何能够高并发-2" class="header-anchor">#</a> Redis单进程单线程的Redis如何能够高并发?</h4> <h4 id="redis如何使用redis实现分布式锁-2"><a href="#redis如何使用redis实现分布式锁-2" class="header-anchor">#</a> Redis如何使用Redis实现分布式锁?</h4> <h4 id="redis分布式锁操作的原子性-redis内部是如何实现的-2"><a href="#redis分布式锁操作的原子性-redis内部是如何实现的-2" class="header-anchor">#</a> Redis分布式锁操作的原子性，Redis内部是如何实现的?</h4> <h3 id="dubbo-2"><a href="#dubbo-2" class="header-anchor">#</a> Dubbo</h3> <h4 id="dubbo完整的一次调用链路介绍-2"><a href="#dubbo完整的一次调用链路介绍-2" class="header-anchor">#</a> Dubbo完整的一次调用链路介绍;</h4> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327161739.png" loading="lazy" class="lazy">
参考:http://dubbo.apache.org/zh-cn/docs/dev/design.html</p> <h4 id="dubbo支持几种负载均衡策略-2"><a href="#dubbo支持几种负载均衡策略-2" class="header-anchor">#</a> Dubbo支持几种负载均衡策略?</h4> <ol><li><p>Random LoadBalance</p> <p>随机，按权重设置随机概率。 在一个截面上碰撞的概率高，但调用量越大分布越均匀，而且按概率使用权重后也比较均匀，有 利于动态调整提供者权重。</p></li> <li><p>RoundRobin LoadBalance</p> <p>轮询，按公约后的权重设置轮询比率。 存在慢的提供者累积请求的问题，比如:第二台机器很慢，但没挂，当请求调到第二台时就卡在 那，久而久之，所有请求都卡在调到第二台上。</p></li> <li><p>LeastActive LoadBalance</p> <p>最少活跃调用数，相同活跃数的随机，活跃数指调用前后计数差。 使慢的提供者收到更少请求，因为越慢的提供者的调用前后计数差会越大。</p></li> <li><p>ConsistentHash LoadBalance</p> <p>一致性 Hash，相同参数的请求总是发到同一提供者。 当某一台提供者挂时，原本发往该提供者的请求，基于虚拟节点，平摊到其它提供者，不会引起 剧烈变动。
算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
缺省只对第一个参数 Hash，如果要修改，请配置
&lt;dubbo:parameter key=&quot;hash.arguments&quot; value=&quot;0,1&quot; /&gt;
缺省用 160 份虚拟节点，如果要修改，请配置
&lt;dubbo:parameter key=&quot;hash.nodes&quot; value=&quot;320&quot; /&gt;</p> <p>参考:http://dubbo.apache.org/zh-cn/docs/user/demos/loadbalance.html</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327161959.png" loading="lazy" class="lazy">
源码分析: <code>http://www.cnblogs.com/wyq178/p/9822731.html</code></p></li></ol> <h4 id="dubbo-provider服务提供者要控制执行并发请求上限-具体怎么做-2"><a href="#dubbo-provider服务提供者要控制执行并发请求上限-具体怎么做-2" class="header-anchor">#</a> Dubbo Provider服务提供者要控制执行并发请求上限，具体怎么做?</h4> <p>服务端并发限流: executes</p> <p>客户端并发限流: actives</p> <p>样例1：
限制 com.foo.BarService 的每个方法，服务器端并发执行(或占用线程池线程数)不能超过 10 个。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span> <span class="token attr-name">executes</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>样例2：</p> <p>限制 <code>com.foo.BarService</code> 的 <code>sayHello</code> 方法，服务器端并发执行(或占用线程池线程数)不能超过 10 个。</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span> <span class="token attr-name">executes</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>method</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>sayHello<span class="token punctuation">&quot;</span></span>  <span class="token attr-name">actives</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>service</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>样例 3</p> <p>限制 <code>com.foo.BarService</code> 的每个方法，每客户端并发执行(或占用连接的请求数)不能超过 10 个:</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>reference</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span> <span class="token attr-name">executes</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>service</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>样例 4
限制 <code>com.foo.BarService</code> 的 <code>sayHello</code> 方法，每客户端并发执行(或占用连接的请求数)不能 超过 10 个:</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>service</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>method</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>sayHello<span class="token punctuation">&quot;</span></span>  <span class="token attr-name">actives</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>service</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>或</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>reference</span> <span class="token attr-name">interface</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.foo.BarService<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">dubbo:</span>method</span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>sayHello<span class="token punctuation">&quot;</span></span>  <span class="token attr-name">actives</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">&quot;</span>10<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token namespace">dubbo:</span>reference</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>参考:http://dubbo.apache.org/zh-cn/docs/user/demos/concurrency-control.html</p> <h4 id="dubbo启动的时候支持几种配置方式-2"><a href="#dubbo启动的时候支持几种配置方式-2" class="header-anchor">#</a> Dubbo启动的时候支持几种配置方式?</h4> <p>XML配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/xml.html</p> <p>属性配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/properties.html</p> <p>API配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/api.html</p> <p>注解配置 http://dubbo.apache.org/zh-cn/docs/user/configuration/annotation.html</p> <h3 id="spring-cloud-2"><a href="#spring-cloud-2" class="header-anchor">#</a> Spring Cloud</h3> <h4 id="spring-cloud熔断机制介绍-2"><a href="#spring-cloud熔断机制介绍-2" class="header-anchor">#</a> Spring Cloud熔断机制介绍;</h4> <p>在Spring Cloud框架里，熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况，当失 败的调用到一定阈值，缺省是5秒内20次调用失败，就会启动熔断机制。熔断机制的注解是 @HystrixCommand，Hystrix会找有这个注解的方法，并将这类方法关联到和熔断器连在一起 的代理上。当前，@HystrixCommand仅当类的注解为@Service或@Component时才会发挥 作用。</p> <h4 id="spring-cloud对比下dubbo-什么场景下该使用spring-cloud-2"><a href="#spring-cloud对比下dubbo-什么场景下该使用spring-cloud-2" class="header-anchor">#</a> Spring Cloud对比下Dubbo，什么场景下该使用Spring Cloud?</h4> <p>两者所解决的问题域不一样，Dubbo的定位始终是一款RPC框架，而Spring Cloud的目的是微服务架构下的一站式解决方案。</p> <p>Spring Cloud抛弃了Dubbo的RPC通信，采用的是基于HTTP的REST方式。 严格来说，这两种方式各有优劣。虽然在一定程度上来说，后者牺牲了服务调用的性能，但也避 免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活，服务提供方和调用方的依赖 只依靠一纸契约，不存在代码级别的强依赖，这在强调快速演化的微服务环境下，显得更为合 适。</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327171104.png" loading="lazy" class="lazy"></p> <p>更多对比: http://blog.51cto.com/13954634/2296010</p> <h3 id="消息队列-2"><a href="#消息队列-2" class="header-anchor">#</a> 消息队列</h3> <h4 id="了解几种消息中间件产品-各产品的优缺点介绍-消息中间件如何保证消息的一致性-2"><a href="#了解几种消息中间件产品-各产品的优缺点介绍-消息中间件如何保证消息的一致性-2" class="header-anchor">#</a> 了解几种消息中间件产品?各产品的优缺点介绍;消息中间件如何保证消息的一致性</h4> <ol><li><p>主动方应用先把消息发送给消息中间件，消息状态标记为待确认;</p></li> <li><p>消息中间件收到消息之后，把消息持久化到消息存储中，但并不向被动方应用投递消息;</p></li> <li><p>消息中间件返回消息持久化结果(成功，或者失效)，主动方应用根据返回结果进行判断如何</p> <p>处理业务操作处理;</p> <ul><li>失败:放弃业务操作处理，结束(必须向上层返回失败结果)</li> <li>成功:执行业务操作处理</li></ul></li> <li><p>业务操作完成后，把业务操作结果(成功/失败)发送给消息中间件;</p></li> <li><p>消息中间件收到业务操作结果后，根据结果进行处理</p> <ol><li>失败:删除消息存储中的消息，结束;</li> <li>成功:更新消息存储中的消息状态为∙待发送(可发送)∙，紧接着执行消息投递;</li></ol></li> <li><p>前面的正向流程都成功后，向被动方应用投递消息;</p></li></ol> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327164828.png" loading="lazy" class="lazy"></p> <h4 id="如何进行消息的重试机制-2"><a href="#如何进行消息的重试机制-2" class="header-anchor">#</a> 如何进行消息的重试机制?</h4> <p>参考:<a href="https://www.cnblogs.com/520playboy/p/6748680.html" target="_blank" rel="noopener noreferrer">Rocket重试机制，消息模式，刷盘方式<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h2 id="数据库-2"><a href="#数据库-2" class="header-anchor">#</a> 数据库</h2> <h3 id="锁机制介绍-行锁、表锁、排他锁、共享锁-2"><a href="#锁机制介绍-行锁、表锁、排他锁、共享锁-2" class="header-anchor">#</a> 锁机制介绍:行锁、表锁、排他锁、共享锁;</h3> <h3 id="乐观锁的业务场景及实现方式-2"><a href="#乐观锁的业务场景及实现方式-2" class="header-anchor">#</a> 乐观锁的业务场景及实现方式;</h3> <h3 id="事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交-2"><a href="#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交-2" class="header-anchor">#</a> 事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</h3> <h3 id="mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么-2"><a href="#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么-2" class="header-anchor">#</a> MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</h3> <p>mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR)，基于行 的复制(row-based replication, RBR)，混合模式复制(mixed-based replication, MBR)。对应 的，binlog的格式也有三种:STATEMENT，ROW，MIXED。
1 STATEMENT模式(SBR)</p> <p>每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的 数据变化，减少了binlog日志量，节约IO，提高性能。缺点是在某些情况下会导致master-slave 中的数据不一致( 如sleep()函数， last_insert_id()，以及user-defined functions(udf)等会出现 问题)
2 ROW模式(RBR)</p> <p>不记录每条 sql 语句的上下文信息，仅需记录哪条数据被修改了，修改成什么样了。而且不会出 现某些特定情况下的存储过程、或 function 、或 trigger 的调用和触发无法被正确复制的问题。缺 点是会产生大量的日志，尤其是 alter table 的时候会让日志暴涨。
3 MIXED模式(MBR)</p> <p>以上两种模式的混合使用，一般的复制使用 <code>STATEMENT</code> 模式保存 <code>binlog</code>，对于 <code>STATEMENT</code> 模式无法复制的操作使用 <code>ROW</code> 模式保存 <code>binlog</code>，MySQL 会根据执行的 SQL 语句选择日志保存方式。</p> <h3 id="mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁-2"><a href="#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁-2" class="header-anchor">#</a> MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</h3> <p>乐观锁</p> <p>用数据版本(Version)记录机制实现，这是乐观锁最常用的一种实现方式。何谓数据版本?即 为数据增加一个版本标识，一般是通过为数据库表增加一个数字类型的 “version” 字段来实 现。当读取数据时，将version字段的值一同读出，数据每更新一次，对此version值加1。当我 们提交更新的时候，判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比 对，如果数据库表当前版本号与第一次取出来的version值相等，则予以更新，否则认为是过期 数据。
悲观锁</p> <p>在进行每次操作时都要通过获取锁才能进行对相同数据的操作，这点跟java中synchronized很 相似，共享锁(读锁)和排它锁(写锁)是悲观锁的不同的实现</p> <p>共享锁(读锁)</p> <p>共享锁又叫做读锁，所有的事务只能对其进行读操作不能写操作，加上共享锁后在事务结束之前
其他事务只能再加共享锁，除此之外其他任何类型的锁都不能再加了。</p> <p>排它锁(写锁)</p> <p>若某个事物对某一行加上了排他锁，只能这个事务对其进行读写，在此事务结束之前，其他事务 不能对其进行加任何锁，其他进程可以读取,不能进行写操作，需等待其释放。</p> <p>表级锁</p> <p>innodb 的行锁是在有索引的情况下,没有索引的表是锁定全表的</p> <p>行级锁</p> <p>行锁又分共享锁和排他锁,由字面意思理解，就是给某一行加上锁，也就是一条记录加上锁。 注意:行级锁都是基于索引的，如果一条SQL语句用不到索引是不会使用行级锁的，会使用表级 锁。</p> <p>更多参考:https://blog.csdn.net/yzj5208/article/details/81288633</p> <h3 id="分布式事务的原理2阶段提交-同步异步阻塞非阻塞-2"><a href="#分布式事务的原理2阶段提交-同步异步阻塞非阻塞-2" class="header-anchor">#</a> 分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</h3> <h3 id="数据库事务隔离级别-mysql默认的隔离级别-2"><a href="#数据库事务隔离级别-mysql默认的隔离级别-2" class="header-anchor">#</a> 数据库事务隔离级别，MySQL默认的隔离级别;</h3> <p>Mysql默认隔离级别:Repeatable Read</p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327165440.png" loading="lazy" class="lazy"></p> <h3 id="spring如何实现事务-2"><a href="#spring如何实现事务-2" class="header-anchor">#</a> Spring如何实现事务;</h3> <p><a href="https://www.cnblogs.com/yixianyixian/p/8372832.html" target="_blank" rel="noopener noreferrer">参考:spring事务管理(详解和实例)<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327165555.png" loading="lazy" class="lazy"></p> <p>Spring 事物四种实现方式:</p> <ul><li>基于编程式事务管理实现</li> <li>基于TransactionProxyFactoryBean的声明式事务管理</li> <li>基于AspectJ的XML声明式事务管理</li> <li>基于注解的声明式事务管理</li></ul> <p>参考:https://blog.csdn.net/zhuxinquan61/article/details/71075051</p> <h3 id="jdbc如何实现事务-2"><a href="#jdbc如何实现事务-2" class="header-anchor">#</a> JDBC如何实现事务;</h3> <p>在JDBC中处理事务，都是通过Connection完成的。</p> <p>同一事务中所有的操作，都在使用同一个Connection对象。</p> <ol><li><p>JDBC中的事务</p> <p>Connection的三个方法与事务有关:</p> <ul><li>setAutoCommit(boolean):设置是否为自动提交事务，如果true(默认值为true)表示自动提 交，也就是每条执行的SQL语句都是一个单独的事务，如果设置为false，那么相当于开启了事务了; con.setAutoCommit(false) 表示开启事务。</li> <li>commit():提交结束事务。</li> <li>rollback():回滚结束事务。</li></ul></li></ol> <p><strong>示例代码</strong></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">try</span><span class="token punctuation">{</span>    
        con<span class="token punctuation">.</span><span class="token function">setAutoCommit</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//开启事务</span>
        <span class="token comment">//......</span>
        con<span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//try的最后提交事务 </span>
         <span class="token punctuation">}</span> <span class="token keyword">catch</span><span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        con<span class="token punctuation">.</span><span class="token function">rollback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//回滚事务</span>
 <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h3 id="嵌套事务实现-2"><a href="#嵌套事务实现-2" class="header-anchor">#</a> 嵌套事务实现；</h3> <p>TODO</p> <h3 id="分布式事务实现-2"><a href="#分布式事务实现-2" class="header-anchor">#</a> 分布式事务实现;</h3> <ol><li><p>基于XA协议的两阶段提交(2PC)</p> <p>XA 规范主要 定义了 ( 全局 ) 事务管理器 ( Transaction Manager ) 和 ( 局部 ) 资源管理器 ( Resource Manager ) 之间的接口。</p></li> <li><p>两阶段提交</p> <p>事务的提交分为两个阶段: 预提交阶段(Pre-Commit Phase) 决策后阶段(Post-Decision Phase)</p></li> <li><p>补偿事务(TCC)</p> <p>针对每个操作，都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段
Try 阶段主要是对业务系统做检测及资源预留
Confirm 阶段主要是对业务系统做确认提交，Try 阶段执行成功并开始执行 Confirm 阶段时， 默认Confirm 阶段是不会出错的。即:只要 Try 成功，Confirm 一定成功。
Cancel 阶段主要是在业务执行错误，需要回滚的状态下执行的业务取消，预留资源释放</p></li> <li><p>本地消息表(MQ 异步确保)</p> <p>其基本的设计思想是将远程分布式事务拆分成一系列的本地事务。</p></li> <li><p>MQ 事务消息</p> <p>有一些第三方的 MQ 是支持事务消息的，比如 RocketMQ，他们支持事务消息的方式也是类似 于采用的二阶段提交，但是市面上一些主流的 MQ 都是不支持事务消息的，比如 RabbitMQ 和 Kafka 都不支持。</p></li> <li><p>Sagas 事务模型</p> <p>该模型其核心思想就是拆分分布式系统中的长事务为多个短事务，或者叫多个本地事务，然后由 Sagas 工作流引擎负责协调，如果整个流程正常结束，那么就算是业务成功完成，如果在这过程 中实现失败，那么Sagas工作流引擎就会以相反的顺序调用补偿操作，重新进行业务回滚。</p></li> <li><p>其他补偿方式</p> <p>加入详细日志记录的，一旦系统内部引发类似致命异常，会有邮件通知。同时，后台会有定时任 务扫描和分析此类日志，检查出这种特殊的情况，会尝试通过程序来补偿并邮件通知相关人员。 在某些特殊的情况下，还会有 &quot;人工补偿&quot; 的，这也是最后一道屏障。</p></li></ol> <p>参考: https://www.javazhiyin.com/573.html</p> <h3 id="sql的整个解析、执行过程原理、sql行转列-2"><a href="#sql的整个解析、执行过程原理、sql行转列-2" class="header-anchor">#</a> SQL的整个解析、执行过程原理、SQL行转列;</h3> <p><strong>整体架构</strong></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327170816.png" loading="lazy" class="lazy"></p> <p><strong>SQL解析</strong></p> <p><img alt="" data-src="https://cdn.jsdelivr.net/gh/janker0718/image_store@master/img/20220327170903.png" loading="lazy" class="lazy"></p> <p><strong>行转列、列转行</strong></p> <p>参考:https://blog.csdn.net/jx_870915876/article/details/52403472</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/janker0718/ShareJava/edit/master/docs/md/java/interview/book.md" target="_blank" rel="noopener noreferrer">在 GitHub 上编辑此页</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="last-updated"><span class="prefix">上次更新: </span> <span class="time">3/30/2022,</span></div></footer> <div class="page-nav"><p class="inner"><!----> <span class="next"><a href="/md/java/interview/resume.html">
          面试 - 简历
        </a>
        →
      </span></p></div> </main></div> <aside class="page-sidebar"> <div class="page-side-toolbar"><div class="option-box-toc-fixed"><div class="toc-container-sidebar"><div class="pos-box"><div class="icon-arrow"></div> <div class="scroll-box" style="max-height:650px"><div style="font-weight:bold;text-align:center;">面试- 小册</div> <hr> <div class="toc-box"><ul class="toc-sidebar-links"><li><a href="/md/java/interview/book.html#jvm" class="toc-sidebar-link">JVM</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jvm内存模型-gc机制和原理" class="toc-sidebar-link">JVM内存模型，GC机制和原理;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#gc分哪两种-minor-gc-和full-gc有什么区别-什么时候会触发full-gc-分别采用什么算法" class="toc-sidebar-link">GC分哪两种，Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jvm里的有几种classloader-为什么会有多种" class="toc-sidebar-link">JVM里的有几种classloader，为什么会有多种?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#什么是双亲委派机制-介绍一些运作过程-双亲委派模型的好处" class="toc-sidebar-link">什么是双亲委派机制?介绍一些运作过程，双亲委派模型的好处;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#什么情况下我们需要破坏双亲委派模型" class="toc-sidebar-link">什么情况下我们需要破坏双亲委派模型;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#常见的jvm调优方法有哪些-可以具体到调整哪个参数-调成什么值" class="toc-sidebar-link">常见的JVM调优方法有哪些?可以具体到调整哪个参数，调成什么值?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jvm虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的" class="toc-sidebar-link">JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;</a></li></ul></li><li><a href="/md/java/interview/book.html#java基础、java进阶" class="toc-sidebar-link">Java基础、Java进阶</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#红黑树的实现原理和应用场景" class="toc-sidebar-link">红黑树的实现原理和应用场景;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#nio是什么-适用于何种场景" class="toc-sidebar-link">NIO是什么?适用于何种场景?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#java9比java8改进了什么" class="toc-sidebar-link">Java9比Java8改进了什么;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#hashmap内部的数据结构是什么-底层是怎么实现的" class="toc-sidebar-link">HashMap内部的数据结构是什么?底层是怎么实现的?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#说说反射的用途及实现-反射是不是很慢-我们在项目中是否要避免使用反射" class="toc-sidebar-link">说说反射的用途及实现，反射是不是很慢，我们在项目中是否要避免使用反射;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#说说自定义注解的场景及实现" class="toc-sidebar-link">说说自定义注解的场景及实现;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#list-和-map-区别" class="toc-sidebar-link">List 和 Map 区别</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#arraylist-与-linkedlist-区别-arraylist-与-vector-区别" class="toc-sidebar-link">Arraylist 与 LinkedList 区别，ArrayList 与 Vector 区别;</a></li></ul></li><li><a href="/md/java/interview/book.html#多线程并发" class="toc-sidebar-link">多线程并发</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#线程池的原理-为什么要创建线程池-创建线程池的方式" class="toc-sidebar-link">线程池的原理，为什么要创建线程池?创建线程池的方式;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#线程的生命周期-什么时候会出现僵死进程" class="toc-sidebar-link">线程的生命周期，什么时候会出现僵死进程;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#说说线程安全问题-什么实现线程安全-如何实现线程安全" class="toc-sidebar-link">说说线程安全问题，什么实现线程安全，如何实现线程安全;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#创建线程池有哪几个核心参数-如何合理配置线程池的大小" class="toc-sidebar-link">创建线程池有哪几个核心参数? 如何合理配置线程池的大小?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#volatile、threadlocal的使用场景和原理" class="toc-sidebar-link">volatile、ThreadLocal的使用场景和原理;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#threadlocal-什么时候会出现oom的情况-为什么" class="toc-sidebar-link">ThreadLocal 什么时候会出现OOM的情况?为什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性" class="toc-sidebar-link">synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;</a></li></ul></li><li><a href="/md/java/interview/book.html#spring" class="toc-sidebar-link">Spring</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-aop的实现原理和场景" class="toc-sidebar-link">Spring AOP的实现原理和场景?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-bean的作用域和生命周期" class="toc-sidebar-link">Spring bean的作用域和生命周期;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-boot比spring做了哪些改进" class="toc-sidebar-link">Spring Boot比Spring做了哪些改进?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-5比spring4做了哪些改进" class="toc-sidebar-link">Spring 5比Spring4做了哪些改进;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#如何自定义一个spring-boot-starter" class="toc-sidebar-link">如何自定义一个Spring Boot Starter?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-ioc是什么-优点是什么" class="toc-sidebar-link">Spring IOC是什么?优点是什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#springmvc、动态代理、反射、aop原理、事务隔离级别" class="toc-sidebar-link">SpringMVC、动态代理、反射、AOP原理、事务隔离级别;</a></li></ul></li><li><a href="/md/java/interview/book.html#框架-中间件" class="toc-sidebar-link">框架|中间件</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#redis" class="toc-sidebar-link">Redis</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#dubbo" class="toc-sidebar-link">Dubbo</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-cloud" class="toc-sidebar-link">Spring Cloud</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#消息队列" class="toc-sidebar-link">消息队列</a></li></ul></li><li><a href="/md/java/interview/book.html#数据库" class="toc-sidebar-link">数据库</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#锁机制介绍-行锁、表锁、排他锁、共享锁" class="toc-sidebar-link">锁机制介绍:行锁、表锁、排他锁、共享锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#乐观锁的业务场景及实现方式" class="toc-sidebar-link">乐观锁的业务场景及实现方式;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交" class="toc-sidebar-link">事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么" class="toc-sidebar-link">MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁" class="toc-sidebar-link">MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务的原理2阶段提交-同步异步阻塞非阻塞" class="toc-sidebar-link">分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#数据库事务隔离级别-mysql默认的隔离级别" class="toc-sidebar-link">数据库事务隔离级别，MySQL默认的隔离级别;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring如何实现事务" class="toc-sidebar-link">Spring如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jdbc如何实现事务" class="toc-sidebar-link">JDBC如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#嵌套事务实现" class="toc-sidebar-link">嵌套事务实现；</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务实现" class="toc-sidebar-link">分布式事务实现;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#sql的整个解析、执行过程原理、sql行转列" class="toc-sidebar-link">SQL的整个解析、执行过程原理、SQL行转列;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#dubbo-2" class="toc-sidebar-link">Dubbo</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-cloud-2" class="toc-sidebar-link">Spring Cloud</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#消息队列-2" class="toc-sidebar-link">消息队列</a></li></ul></li><li><a href="/md/java/interview/book.html#数据库-2" class="toc-sidebar-link">数据库</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#锁机制介绍-行锁、表锁、排他锁、共享锁-2" class="toc-sidebar-link">锁机制介绍:行锁、表锁、排他锁、共享锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#乐观锁的业务场景及实现方式-2" class="toc-sidebar-link">乐观锁的业务场景及实现方式;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交-2" class="toc-sidebar-link">事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么-2" class="toc-sidebar-link">MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁-2" class="toc-sidebar-link">MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务的原理2阶段提交-同步异步阻塞非阻塞-2" class="toc-sidebar-link">分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#数据库事务隔离级别-mysql默认的隔离级别-2" class="toc-sidebar-link">数据库事务隔离级别，MySQL默认的隔离级别;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring如何实现事务-2" class="toc-sidebar-link">Spring如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jdbc如何实现事务-2" class="toc-sidebar-link">JDBC如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#嵌套事务实现-2" class="toc-sidebar-link">嵌套事务实现；</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务实现-2" class="toc-sidebar-link">分布式事务实现;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#sql的整个解析、执行过程原理、sql行转列-2" class="toc-sidebar-link">SQL的整个解析、执行过程原理、SQL行转列;</a></li></ul></li></ul></div></div></div></div></div> <div class="option-box"><a title="点击切换全屏" style="text-align:center;padding-left:2px;"><img src="/images/system/full.png" width="30px" class="nozoom"> <span style="color:gray;font-size:11px;font-weight:400;">全屏看</span></a></div> <div class="option-box-toc-over"><img src="/images/system/mulu.png" class="nozoom"> <span class="show-txt">目录</span> <div class="toc-container"><div class="pos-box"><div class="icon-arrow"></div> <div class="scroll-box" style="max-height:550px"><div style="font-weight:bold;text-align:center;">面试- 小册</div> <hr> <div class="toc-box"><ul class="toc-sidebar-links"><li><a href="/md/java/interview/book.html#jvm" class="toc-sidebar-link">JVM</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jvm内存模型-gc机制和原理" class="toc-sidebar-link">JVM内存模型，GC机制和原理;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#gc分哪两种-minor-gc-和full-gc有什么区别-什么时候会触发full-gc-分别采用什么算法" class="toc-sidebar-link">GC分哪两种，Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jvm里的有几种classloader-为什么会有多种" class="toc-sidebar-link">JVM里的有几种classloader，为什么会有多种?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#什么是双亲委派机制-介绍一些运作过程-双亲委派模型的好处" class="toc-sidebar-link">什么是双亲委派机制?介绍一些运作过程，双亲委派模型的好处;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#什么情况下我们需要破坏双亲委派模型" class="toc-sidebar-link">什么情况下我们需要破坏双亲委派模型;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#常见的jvm调优方法有哪些-可以具体到调整哪个参数-调成什么值" class="toc-sidebar-link">常见的JVM调优方法有哪些?可以具体到调整哪个参数，调成什么值?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jvm虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的" class="toc-sidebar-link">JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;</a></li></ul></li><li><a href="/md/java/interview/book.html#java基础、java进阶" class="toc-sidebar-link">Java基础、Java进阶</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#红黑树的实现原理和应用场景" class="toc-sidebar-link">红黑树的实现原理和应用场景;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#nio是什么-适用于何种场景" class="toc-sidebar-link">NIO是什么?适用于何种场景?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#java9比java8改进了什么" class="toc-sidebar-link">Java9比Java8改进了什么;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#hashmap内部的数据结构是什么-底层是怎么实现的" class="toc-sidebar-link">HashMap内部的数据结构是什么?底层是怎么实现的?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#说说反射的用途及实现-反射是不是很慢-我们在项目中是否要避免使用反射" class="toc-sidebar-link">说说反射的用途及实现，反射是不是很慢，我们在项目中是否要避免使用反射;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#说说自定义注解的场景及实现" class="toc-sidebar-link">说说自定义注解的场景及实现;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#list-和-map-区别" class="toc-sidebar-link">List 和 Map 区别</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#arraylist-与-linkedlist-区别-arraylist-与-vector-区别" class="toc-sidebar-link">Arraylist 与 LinkedList 区别，ArrayList 与 Vector 区别;</a></li></ul></li><li><a href="/md/java/interview/book.html#多线程并发" class="toc-sidebar-link">多线程并发</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#线程池的原理-为什么要创建线程池-创建线程池的方式" class="toc-sidebar-link">线程池的原理，为什么要创建线程池?创建线程池的方式;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#线程的生命周期-什么时候会出现僵死进程" class="toc-sidebar-link">线程的生命周期，什么时候会出现僵死进程;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#说说线程安全问题-什么实现线程安全-如何实现线程安全" class="toc-sidebar-link">说说线程安全问题，什么实现线程安全，如何实现线程安全;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#创建线程池有哪几个核心参数-如何合理配置线程池的大小" class="toc-sidebar-link">创建线程池有哪几个核心参数? 如何合理配置线程池的大小?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#volatile、threadlocal的使用场景和原理" class="toc-sidebar-link">volatile、ThreadLocal的使用场景和原理;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#threadlocal-什么时候会出现oom的情况-为什么" class="toc-sidebar-link">ThreadLocal 什么时候会出现OOM的情况?为什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性" class="toc-sidebar-link">synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;</a></li></ul></li><li><a href="/md/java/interview/book.html#spring" class="toc-sidebar-link">Spring</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-aop的实现原理和场景" class="toc-sidebar-link">Spring AOP的实现原理和场景?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-bean的作用域和生命周期" class="toc-sidebar-link">Spring bean的作用域和生命周期;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-boot比spring做了哪些改进" class="toc-sidebar-link">Spring Boot比Spring做了哪些改进?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-5比spring4做了哪些改进" class="toc-sidebar-link">Spring 5比Spring4做了哪些改进;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#如何自定义一个spring-boot-starter" class="toc-sidebar-link">如何自定义一个Spring Boot Starter?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-ioc是什么-优点是什么" class="toc-sidebar-link">Spring IOC是什么?优点是什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#springmvc、动态代理、反射、aop原理、事务隔离级别" class="toc-sidebar-link">SpringMVC、动态代理、反射、AOP原理、事务隔离级别;</a></li></ul></li><li><a href="/md/java/interview/book.html#框架-中间件" class="toc-sidebar-link">框架|中间件</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#redis" class="toc-sidebar-link">Redis</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#dubbo" class="toc-sidebar-link">Dubbo</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-cloud" class="toc-sidebar-link">Spring Cloud</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#消息队列" class="toc-sidebar-link">消息队列</a></li></ul></li><li><a href="/md/java/interview/book.html#数据库" class="toc-sidebar-link">数据库</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#锁机制介绍-行锁、表锁、排他锁、共享锁" class="toc-sidebar-link">锁机制介绍:行锁、表锁、排他锁、共享锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#乐观锁的业务场景及实现方式" class="toc-sidebar-link">乐观锁的业务场景及实现方式;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交" class="toc-sidebar-link">事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么" class="toc-sidebar-link">MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁" class="toc-sidebar-link">MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务的原理2阶段提交-同步异步阻塞非阻塞" class="toc-sidebar-link">分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#数据库事务隔离级别-mysql默认的隔离级别" class="toc-sidebar-link">数据库事务隔离级别，MySQL默认的隔离级别;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring如何实现事务" class="toc-sidebar-link">Spring如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jdbc如何实现事务" class="toc-sidebar-link">JDBC如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#嵌套事务实现" class="toc-sidebar-link">嵌套事务实现；</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务实现" class="toc-sidebar-link">分布式事务实现;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#sql的整个解析、执行过程原理、sql行转列" class="toc-sidebar-link">SQL的整个解析、执行过程原理、SQL行转列;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#dubbo-2" class="toc-sidebar-link">Dubbo</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring-cloud-2" class="toc-sidebar-link">Spring Cloud</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#消息队列-2" class="toc-sidebar-link">消息队列</a></li></ul></li><li><a href="/md/java/interview/book.html#数据库-2" class="toc-sidebar-link">数据库</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#锁机制介绍-行锁、表锁、排他锁、共享锁-2" class="toc-sidebar-link">锁机制介绍:行锁、表锁、排他锁、共享锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#乐观锁的业务场景及实现方式-2" class="toc-sidebar-link">乐观锁的业务场景及实现方式;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#事务介绍-分布式事物的理解-常见的解决方案有哪些-什么事两阶段提交、三阶段提交-2" class="toc-sidebar-link">事务介绍，分布式事物的理解，常见的解决方案有哪些，什么事两阶段提交、三阶段提交;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql记录binlog的方式主要包括三种模式-每种模式的优缺点是什么-2" class="toc-sidebar-link">MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#mysql锁-悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁-2" class="toc-sidebar-link">MySQL锁，悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务的原理2阶段提交-同步异步阻塞非阻塞-2" class="toc-sidebar-link">分布式事务的原理2阶段提交，同步异步阻塞非阻塞;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#数据库事务隔离级别-mysql默认的隔离级别-2" class="toc-sidebar-link">数据库事务隔离级别，MySQL默认的隔离级别;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#spring如何实现事务-2" class="toc-sidebar-link">Spring如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#jdbc如何实现事务-2" class="toc-sidebar-link">JDBC如何实现事务;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#嵌套事务实现-2" class="toc-sidebar-link">嵌套事务实现；</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#分布式事务实现-2" class="toc-sidebar-link">分布式事务实现;</a></li><li class="toc-sidebar-sub-header"><a href="/md/java/interview/book.html#sql的整个解析、执行过程原理、sql行转列-2" class="toc-sidebar-link">SQL的整个解析、执行过程原理、SQL行转列;</a></li></ul></li></ul></div></div></div></div></div> <div class="option-box"><img src="/images/system/wechat.png" class="nozoom"> <span class="show-txt">手机看</span> <div class="toc-container"><div class="pos-box"><div class="icon-arrow"></div> <div class="scroll-box" style="text-align:center"><span style="font-size:0.9rem">微信扫一扫</span> <img height="180px" src="https://api.qrserver.com/v1/create-qr-code/?data=https://www.share-java.com/md/java/interview/book.html" style="margin:10px;">
                可以<b>手机看</b>或分享至<b>朋友圈</b></div></div></div></div> <div class="option-box"><img src="/images/system/toggle.png" width="30px" class="nozoom"> <span class="show-txt">左栏</span></div> <div class="option-box"><img src="/images/system/download-2.png" width="25px" class="nozoom"> <span class="show-txt">下资料</span> <div class="toc-container"><div class="pos-box"><div class="icon-arrow"></div> <div class="scroll-box" style="text-align:center"><span style="font-size:0.8rem;font-weight:bold;">扫描公众号，回复<span style="color:red;">“66”</span>下载<span style="color:red;">1TB+</span>学习技术资料、PDF书籍、简历模板「无任何套路」</span> <img src="https://cdn.jsdelivr.net/gh/janker0718/image_store/img/20220103214503494.png" height="180px" style="margin:10px;"> <b>公众号:</b> 爪哇干货分享
              </div></div></div></div> <!----> <div title="面试 - 简历" class="option-box" style="padding-left:2px;text-align:center;"><a href="/md/java/interview/resume.html"><img src="/images/system/next2.png" width="30px" class="nozoom"> <span class="show-txt">下一篇</span></a></div></div>  <div class="page-side-sitemap"><div class="option-box"><img src="/images/system/sitemap.png" class="nozoom img"> <span class="show-txt">站点图</span> <div class="sitemap-container"><h4>站点导航图
              <a href="/md/about/me/about-me.html" class="sitemap-top-link"> 关于我</a> <a href="/md/about/me/about-arch.html" class="sitemap-top-link"> 关于学习</a></h4> <table class="sitemap-table"><tr><td nowrap="nowrap"><div class="sitemap-col-group">常用搜索</div></td> <td><div class="sitemap-col-item"><a href="http://www.baidu.com/" target="_blank" title="百度">  
          百度
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="http://www.google.com/" target="_blank" title="Google">  
          Google
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="http://www.bing.com/" target="_blank" title="Bing">  
          Bing
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://github.com" target="_blank" title="Github">  
          Github
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://www.programcreek.com/java-api-examples/index.php" target="_blank" title="搜代码">  
          搜代码
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></td> <!----></tr><tr><td nowrap="nowrap"><div class="sitemap-col-group">技术社区</div></td> <td><div class="sitemap-col-item"><a href="http://www.csdn.net/" target="_blank" title="CDSN">  
          CDSN
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="http://www.cnblogs.com/" target="_blank" title="博客园">  
          博客园
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://www.oschina.net" target="_blank" title="OSChina">  
          OSChina
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://segmentfault.com/" target="_blank" title="思否">  
          思否
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://juejin.im" target="_blank" title="掘金">  
          掘金
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://www.linuxidc.com/" target="_blank" title="Linux公社">  
          Linux公社
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://www.ibm.com/developerworks/cn/" target="_blank" title="IBM 开发者">  
          IBM 开发者
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="sitemap-col-item"><a href="https://stackoverflow.com" target="_blank" title="StackOverflow">  
          StackOverflow
          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></td> <!----></tr></table></div></div></div> <!----> </aside></div><div class="global-ui"><div class="read-more-wrap" style="display:none;position:absolute;bottom:0px;z-index:9999;width:100%;margin-top:-100px;font-family:PingFangSC-Regular, sans-serif;"><div id="read-more-mask" style="position: relative; height: 200px; background: -webkit-gradient(linear, 0 0%, 0 100%, from(rgba(255, 255, 255, 0)), to(rgb(255, 255, 255)));"></div> <a id="read-more-btn" target="_self" style="position: absolute; left: 50%; top: 70%; bottom: 30px; transform: translate(-50%, -50%); width: 160px; height: 36px; line-height: 36px; font-size: 15px; text-align: center; border: 1px solid rgb(222, 104, 109); color: rgb(222, 104, 109); background: rgb(255, 255, 255); cursor: pointer; border-radius: 6px;">阅读全文</a> <div id="btw-modal-wrap" style="display: none;"><div id="btw-mask" style="position: fixed; top: 0px; right: 0px; bottom: 0px; left: 0px; opacity: 0.7; z-index: 999; background: rgb(0, 0, 0);"></div> <div id="btw-modal" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 300px; text-align: center; font-size: 13px; background: rgb(255, 255, 255); border-radius: 10px; z-index: 9999; font-family: PingFangSC-Regular, sans-serif;"><span id="btw-modal-close-btn" style="position: absolute; top: 5px; right: 15px; line-height: 34px; font-size: 34px; cursor: pointer; opacity: 0.2; z-index: 9999; color: rgb(0, 0, 0); background: none; border: none; outline: none;">×</span> <p id="btw-modal-header" style="margin-top: 40px; line-height: 1.8; font-size: 13px;">
                扫码或搜索：<span style="color: #E9405A; font-weight: bold;">爪哇干货分享</span> <br>发送：<span id="fustack-token" class="token" style="color: #e9415a; font-weight: bold; font-size: 17px; margin-bottom: 45px;">10086</span> <br>即可<span style="color: #e9415a; font-weight: bold;">立即永久</span>解锁本站全部文章</p> <img src="/images/personal/qrcode.png" style="width: 180px; margin-top: 10px; margin-bottom: 30px; border: 8px solid rgb(230, 230, 230);"></div></div></div><div class="pay-read-more-wrap" style="display:none;position:absolute;bottom:0px;z-index:9999;width:100%;margin-top:-100px;font-family:PingFangSC-Regular, sans-serif;"><div id="pay-read-more-mask" style="position: relative; height: 200px; background: -webkit-gradient(linear, 0 0%, 0 100%, from(rgba(255, 255, 255, 0)), to(rgb(255, 255, 255)));"></div> <a id="pay-read-more-btn" target="_blank" style="position: absolute; left: 50%; top: 70%; bottom: 30px; transform: translate(-50%, -50%); width: 160px; height: 36px; line-height: 36px; font-size: 15px; text-align: center; border: 1px solid rgb(222, 104, 109); color: rgb(222, 104, 109); background: rgb(255, 255, 255); cursor: pointer; border-radius: 6px;">付费阅读</a></div><!----><div></div></div></div>
    <script src="/assets/js/cg-styles.js?v=1648640762568" defer></script><script src="/assets/js/cg-4.js?v=1648640762568" defer></script><script src="/assets/js/cg-3.js?v=1648640762568" defer></script><script src="/assets/js/cg-23.js?v=1648640762568" defer></script><script src="/assets/js/cg-5.js?v=1648640762568" defer></script><script src="/assets/js/cg-6.js?v=1648640762568" defer></script><script src="/assets/js/cg-app.js?v=1648640762568" defer></script>
  </body>
</html>
